Underlying principle of Spring Aop

1, agent

What is agent mode
Through the proxy control object access, you can access the method of an object in detail, in this method call processing, or call post-processing. The core technology of AOP is face to face programming.

Application scenario of agent mode
Spring AOP, principle of things, log printing, permission control, remote call, security agent can hide real roles

Classification of agents
Static proxy (static definition proxy class)
Dynamic proxy (dynamically generate proxy class)

  • Jdk comes with dynamic agent, Cglib and javaassist (bytecode operation Library)

What is static agent
The source code of the agent class is created by the programmer or generated by the tool, and then the agent class is compiled. Static means that the bytecode file of the agent class already exists before the program runs. The relationship between the agent class and the delegate class is determined before the program runs.

public interface IUserDao {
    void save();
}
public class UserDao implements IUserDao {
    public void save() {
        System.out.println("Data saved...");
    }
}
//proxy class
public class UserDaoProxy implements IUserDao {
    private IUserDao target;public UserDaoProxy(IUserDao iuserDao) {
        this.target = iuserDao;
    }public void save() {
        System.out.println("Opening things...");
        target.save();
        System.out.println("Closing things...");
    }}

What is dynamic agent

1. Proxy object, no need to implement interface
2. The generation of proxy object is to use the API of JDK to dynamically build proxy object in memory (we need to specify the type of interface to create proxy object / target object)
3. Dynamic agent is also called JDK agent and interface agent

  • JDK dynamic agent

1) Principle: create a proxy class according to the class loader and interface (this proxy class is the implementation class of the interface, so you must use the interface to generate an interface oriented proxy, which is located under the java.lang.reflect package)
2) Implementation mode:

  1. Create your own call handler by implementing the InvocationHandler interface, InvocationHandler handler = new invocationhandlerimpl ( );
  2. Create a dynamic Proxy class by specifying a ClassLoader object and a set of interface s for the Proxy Class clazz = Proxy.getProxyClass(classLoader,new Class [] { };
  3. Get the constructor of the dynamic proxy class through the reflection mechanism. Its parameter type is to call the processor interface type constructor = clazz.getconstructor (new class [] {invocationhandler. Class});
  4. To create an instance of a proxy class through a constructor, you need to pass the calling processor object as a parameter to Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));

Disadvantages: jdk dynamic proxy must be interface oriented, and the target business class must implement the interface

// Every time a dynamic proxy class object is generated, the invoking handler object of the InvocationHandler interface is implemented 
public class InvocationHandlerImpl implements InvocationHandler {
    private Object target;// This is actually a business implementation class object, which is used to call specific business methods
    // Pass in the target object through the constructor
    public InvocationHandlerImpl(Object target) {
        this.target = target;
    }public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        System.out.println("Call start processing");
        result = method.invoke(target, args);
        System.out.println("Call end processing");
        return result;
    }public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException,
            IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        // Represented object
        IUserDao userDao = new UserDao();
        InvocationHandlerImpl invocationHandlerImpl = new InvocationHandlerImpl(userDao);
        ClassLoader loader = userDao.getClass().getClassLoader();
        Class<?>[] interfaces = userDao.getClass().getInterfaces();
        // Main loader, a set of interfaces and call processing dynamic agent instance
        IUserDao newProxyInstance = (IUserDao) Proxy.newProxyInstance(loader, interfaces, invocationHandlerImpl);
        newProxyInstance.save();
    }}
  • CGLIB dynamic agent

Principle: use the asm open source package to load the class file of the proxy object class, and modify its bytecode to generate a subclass for processing.
What is CGLIB dynamic agent
Using cglib[Code Generation Library] to realize dynamic proxy does not require that the proxy class must implement the interface. The bottom layer uses asm bytecode generation framework to generate the bytecode of the proxy class

public class CglibProxy implements MethodInterceptor {
    private Object targetObject;
    // If the target type here is Object, any parameter can be accepted as the proxy class to realize dynamic proxy
    public Object getInstance(Object target) {
        // Set the class that needs to create the subclass
        this.targetObject = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Opening things");
        Object result = proxy.invoke(targetObject, args);
        System.out.println("Closing things");
        // Return proxy object
        return result;
    }
    public static void main(String[] args) {
        CglibProxy cglibProxy = new CglibProxy();
        UserDao userDao = (UserDao) cglibProxy.getInstance(new UserDao());
        userDao.save();
    }
}

Dynamic difference between CGLIB dynamic agent and JDK
java dynamic proxy uses reflection mechanism to generate an anonymous class that implements the proxy interface. It calls InvokeHandler before calling the specific method.
cglib dynamic proxy uses asm open source package to load the class file of proxy object class and modify its bytecode to generate subclass.

Spring:

1. If the target object implements the interface, the dynamic agent of JDK will be used to implement AOP by default
2. If the target object implements the interface, you can force CGLIB to implement AOP
3. If the target object does not implement the interface, it must adopt CGLIB library, and spring will automatically convert between JDK dynamic agent and CGLIB

JDK dynamic proxy can only generate proxy for the class that implements the interface, not for the class. CGLIB implements the proxy for the class, mainly generates a subclass for the specified class, and covers the methods. Because it is inheritance, it is better not to declare the class or method as final, which can prevent inheritance and polymorphism.

Published 6 original articles, won praise 0, visited 520
Private letter follow

Tags: JDK Spring Java Programming

Posted on Fri, 06 Mar 2020 03:30:17 -0800 by scottshane