Detailed Explanation of Java Dynamic Proxy and Reflection Mechanism

  • 2021-07-09 08:10:41
  • OfStack

Reflex mechanism

Java language provides a basic function, through reflection, we can manipulate this class or object, such as obtaining methods, attributes and constructors in this class.

Dynamic proxy: JDK dynamic proxy, cglib dynamic proxy (spring dynamic proxy).

Static proxy

The relationship between the agent and the agent is determined in advance (during compilation), that is, if the agent class already exists before the program runs, this situation is called static agent

Dynamic agent

The way the proxy class creates the proxy when the program is running. That is, the proxy class is not defined in the Java code, but is dynamically generated at run time according to our "instructions" in the Java code.

The advantages of dynamic proxy over static proxy are:

Dynamic proxy can be very convenient to proxy class functions for a unified 1 processing (invoke), instead of modifying the functions of each proxy class, more flexible and extended.

Dynamic Proxy for JDK (Interface Dependent)

In the dynamic proxy mechanism of Java, there are two important classes or interfaces, one is an InvocationHandler interface, and the other is an Proxy class. The InvocationHandler interface is implemented for the dynamic proxy class and is responsible for handling the operations of the proxy object The Proxy class is used to create a dynamic proxy class instance object. Only when you get this object can you call the method that needs proxy. The proxy class of the dynamic proxy is modified on the static proxy class. The dynamic proxy class implements the InvocationHandler interface, overrides the Invoke method, and the Invoke method is executed by passing in the proxy class methods and parameters.

Examples are as follows:


public interface AppService {
 void createApp(String name);
 void deleteApp(String name);
}
 
// Agent class (such as WeChat business agent) 
public class AppServiceImpl implements AppService{
 
 @Override
 public void createApp(String name) {
  System.out.print("App["+name+"] has been created.");
 }
 
 @Override
 public void deleteApp(String name) {
  System.out.print("App["+name+"] has been delete.");
 }
}
 
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
 
public class LoggerInterceptor implements InvocationHandler {
 private Object target; // Delegate class ( Proxy class ) Examples of, such as manufacturers 
 public LoggerInterceptor(Object target){ 
  this.target = target; 
 } 
 @Override
 public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
  System.out.println("Entered "+target.getClass().getName()+"-"+method.getName()+",with arguments{"+args[0]+"}"); 
  Object result = method.invoke(target, args);
  // Invoke the method of the target object   Invoke the vendor's method ( createApp ) and parameters ( Kevin Test )) 
  System.out.println("Before return:"+result); 
  return result; 
 }
 
}

import java.lang.reflect.Proxy;
 
public class test {
 
public static void main(String[] args) {
          AppService target = new AppServiceImpl();// Generate the target object  ( Objects of proxy class )
          // Next, create the proxy object 
          AppService proxy = (AppService) Proxy.newProxyInstance(
          target.getClass().getClassLoader(),
          target.getClass().getInterfaces(), new LoggerInterceptor(target));
          proxy.createApp("Kevin Test1");
          proxy.deleteApp("Kevin Test2");
    }
 
}
 
/**
* 1 , jdk The implementation of the dynamic proxy is dependent on the interface. Firstly, the interface is used to define the operation specification. 
* 2 , through proxy Class calls the operation of the proxy object. 
* 3 And this operation is distributed to InvocationHandler Interface's invoke Specific implementation of the method 
*
*  In java There are two important classes or interfaces in the dynamic proxy mechanism of, 1 One is InvocationHandler Interface, another 1 One is  Proxy Class, this class and interface are necessary to implement our dynamic proxy. 
InvocationHandler Interface is implemented for dynamic proxy classes and is responsible for handling the operations of proxy objects, while Proxy Is used to create a dynamic proxy class instance object, because only when we get this object can we call those methods that require proxy. 
*
*  The parameters of this method have the following meanings 
proxy Represents a dynamic proxy object 
method Represents the method being executed 
args Represents the arguments passed in by the currently executing method 
 Return value: Represents the return value of the currently executing method 
*
*  As above: 
*  Used Proxy Class newProxyInstance Method generates a proxy object, and then uses this object to call the createApp() And deleteApp() Method, 
*  In fact, the system will put this 2 Methods distributed to invoke() Method area execution. Among them proxy The class of object is created dynamically by the system, which actually implements our business interface AppService
*
*/

cglib Dynamic Proxy (Inheritance Mode)

MethodInterceptor is used in cglib dynamic proxy to implement dynamic proxy classes.

In the interceptor MethodInterceptor, the proxy method is called by the InvokSuper method of MethodProxy.

The MethodProxy class generates the proxy method and the signature of the proxy method.

The difference between JDK dynamic proxy and Cglib dynamic proxy:

The JDK dynamic proxy is the interface that implements the proxy object, and the Cglib inherits the proxy object. Because Cglib is an inheritance mechanism, it cannot proxy methods decorated by final. JDK and Cglib both produce bytecode during operation, JDK writes class bytecode directly, and Cglib writes class bytecode using ASM framework. The cglib proxy implementation is more complex, and generating proxy analogies is less efficient than JDK. JDK calls proxy methods through reflection implementation mechanism, while cglib calls methods directly through Fashclass mechanism, which is more efficient.

Fastcalss mechanism:

Generates 1 class for each of the proxy class and the proxy class, and this class assigns 1 index to the methods of the proxy class or the proxy class.

This index is used as an input parameter, and Fashclass can directly locate the method to be called and call it directly. This eliminates the reflection call, so the efficiency is high.


Related articles: