[Spring AOP] Aspect-oriented programming



Spring AOP aspect-oriented programming

1. AOP concept

Insert picture description here

  • Aspect-oriented (aspect) programming,The use of AOP can isolate each part of the business logic, thereby reducing the coupling between the various parts of the business logic, Improve the reusability of the program, and improve the efficiency of development at the same time.

  • To put it simply: add new functions to the trunk without modifying the source code.

  • Take the login interface as an example:
    Insert picture description here
    after a successful login, we add the function of permission judgment. According to the original method, the source code needs to be modified to add the function of permission judgment. However, using the AOP concept, we add a permission judgment module, which can be declared when needed; when it is not needed, it is not necessary to declare it.

Back to top


2. The underlying principle of AOP-dynamic proxy

① JDK dynamic proxy-with interface

  • Create a 接口实现类proxy object, enhance the method of the class
    Insert picture description here
    when we have 接口UserDao, and contain 方法login(). Generally, the function is realized by creating an overriding method of its implementation class. NowThrough the JDK dynamic proxy, create a proxy object of the UserDao interface implementation class, and add new functions on the basis of the original functions

② CGLIB dynamic proxy — no interface

  • The created 子类proxy object, enhance the method of the class
    Insert picture description here
    as we are 没有接口,只有类User, and contains 方法add(). Generally, it is to inherit from the User class by creating a subclass, use the super keyword inside the method body to call the method of the parent class, and improve it, butThrough CGLIB dynamic proxy, we create a subclass proxy object of the current class to complete

Back to top


Third, the underlying principle of AOP-JDK dynamic proxy implementation

1, using the JDK dynamic proxy, using Proxy 类create proxy object inside the method
Insert picture description here

  • (1)Call the newProxyInstance method
    Insert picture description here
    The method has three parameters:
    • The first parameter, the class loader
    • The second parameter, the class where the enhancement method is located, the interface that this class implements, supports multiple interfaces
    • The third parameter, to achieve this 接口 InvocationHandler, create a proxy object, write the enhanced part
      Insert picture description here

2. Write JDK dynamic proxy code

  • (1) Create interface and define method
package AOP_JDK动态代理;

public interface UserDao {
    
    
    public int add(int a,int b);
    public String update(String id);
}

  • (2) Create an interface implementation class and implement methods
package AOP_JDK动态代理;

public class UserDaoImpl implements UserDao {
    
    
    @Override
    public int add(int a, int b) {
    
    
        System.out.println("add方法执行了...");
        return a+b;
    }

    @Override
    public String update(String id) {
    
    
        System.out.println("update方法执行了...");
        return id;
    }
}

  • (3) Use the Proxy class to create an interface proxy object
package AOP_JDK动态代理;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class JDKProxy {
    
    
    public static void main(String[] args) {
    
    
        // 3.创建接口实现类代理对象
        // 3.1 增强方法所在的类,支持多接口
        Class[] interfaces = {
    
    UserDao.class};
        // 3.2 创建接口实现类对象
        UserDaoImpl userDao = new UserDaoImpl();
        // 3.3 创建代理对象 --- 类加载器、增强方法所在类、实现接口 InvocationHandler,创建代理对象,写增强的部分
        UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(),interfaces,new UserDaoProxy(userDao));
        // 通过代理对象调用增强方法
        int result = dao.add(1,2);
        System.out.println("result:"+result);
    }
}
class UserDaoProxy implements InvocationHandler{
    
    

    // 1.获取代理对象的来源 --- 通过有参构造器进行传递
    private Object obj;
    public UserDaoProxy(Object obj){
    
    
        this.obj = obj;
    }

    // 2.增强的逻辑
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    

        // 方法之前进行处理
        System.out.println("方法之前进行处理..."+method.getName()+":传递的参数..."+ Arrays.toString(args));

        // 被增强的方法执行
        Object result = method.invoke(obj,args);

        // 方法之后进行处理
        System.out.println("方法之后进行处理..."+obj);

        return result;
    }
}

Insert picture description here
supplement:

  • If there are multiple methods, you can method.getName()get the name of the called method, and then make different treatments accordingly.
  // 2.增强的逻辑
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    

        if(method.getName().equals("add"){
    
    
	        // 方法之前进行处理
	        System.out.println("方法之前进行处理..."+method.getName()+":传递的参数..."+ Arrays.toString(args));
	        // 被增强的方法执行
	        Object result = method.invoke(obj,args);
	        // 方法之后进行处理
	        System.out.println("方法之后进行处理..."+obj);

     	    return result;
        } else {
    
    
            ............
    }

Back to top


Guess you like

Origin blog.csdn.net/qq_45797116/article/details/113776727