[Spring Framework] Application of AOP and Dynamic Proxy

一. Spring AOP

       Aspect Oriented Programming (AOP) is the product of the development of software programming thought to a certain stage, it is a useful supplement to Object Oriented Programming (OOP) , and it has become a relatively mature programming method. AOP is suitable for places with horizontal logic, such as access control, transaction management, performance monitoring, etc.

1. Traditional issues:

      In traditional business processing code, operations such as transaction processing and logging are usually performed. Although OOP can achieve code reuse through composition or inheritance, for example, when implementing logging, the code is still scattered into different methods. In this way, there will be a problem. If you want to turn off a function or modify it, you must modify all related methods. This not only increases the workload of developers, but also increases the error rate of the code.

2. Problem solving strategies:

      In order to solve this problem, the idea of ​​AOP came into being. AOP adopts a horizontal extraction mechanism to extract repetitive codes scattered in various methods, and then applies these extracted codes to the places that need to be executed when the program is compiled or run. This method of adopting the horizontal extraction mechanism cannot be achieved by the traditional OOP idea, because OOP can only realize the vertical reuse of the parent-child relationship. Although AOP is a new programming idea, it is not a substitute for OOP, it is just an extension and supplement of OOP .

 3. AOP advantages:

       The use of AOP allows developers to concentrate on the core business when writing business logic, without paying too much attention to the implementation of other business logic, which not only improves the development efficiency , but also enhances the maintainability of the code .

  In the idea of ​​AOP, the relationship between class and aspect is shown in the following figure. We can see that functions such as transactions, logs, permissions and exceptions are added to the methods of Class1 and Class2 through Aspect .

 2. Dynamic proxy

      Through learning, we know that the agent in AOP is an object dynamically generated by the AOP framework, which can be used as the target object. For aspect-oriented programming, in short, it is to add new code to the code segment without changing the original program. function to enhance the code segment. Its design idea comes from the proxy design pattern. Usually, the method of calling the object is as shown in the figure below .

 

      In the proxy mode, a proxy object can be set for the object, and the proxy object provides a proxy method for function(). When the function() method of the original object is called through the function() method of the proxy object, you can add a proxy method The new feature is Enhanced Processing. Enhanced functions can be inserted either before or after the function() of the original object (such as dotted lines)

 

 1. JDK dynamic proxy

      The JDK dynamic proxy is implemented through the java.lang.reflect.Proxy class , and the newProxyInstance() method of the Proxy class can be called to create a proxy object. For classes that use business interfaces, the Spring framework uses the JDK dynamic proxy to implement AOP by default. Demonstrate through a case.

 1.  UserDao.java

package dao;

public interface UserDao {
    public void addUserDao();
    public void deleteUser();
}

2.  UserDaoImpl.java

package dao;

public class UserDaoImpl implements UserDao{
    @Override
    public void addUserDao() {
        System.out.println("添加用户");
    }

    @Override
    public void deleteUser() {
        System.out.println("删除用户");
    }
}

3.  MyAspect.java

package aspect;

public class MyAspect {
    public void check_permission(){
        System.out.println("----模拟检查访问----");
    }
    public void log(){
        System.out.println("----模拟记录日记----");
    }
}

4.  JdkProxy.java

package jdk;

import aspect.MyAspect;
import dao.UserDao;

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

/**
 * Jdk代理类
 */
public class JdkProxy implements InvocationHandler {
    //声明目标类接口
    private UserDao userdao;
//    创建代理方法
    public Object createProxy(UserDao userdao){
        this.userdao=userdao;
        //类加载器
        ClassLoader classLoader=JdkProxy.class.getClassLoader();
        //被代理对象实现的所有接口
        Class[] clazz=userdao.getClass().getInterfaces();
        //使用代理类进行增强,返回的是代理后的对象
        return Proxy.newProxyInstance(classLoader,clazz,this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //声明切面
        MyAspect myAspect=new MyAspect();
        //前增强
        myAspect.check_permission();
        //在目标上调用方法,并传入参数
        Object obj=method.invoke(userdao,args);
        //后增强
        myAspect.log();
        return obj;
    }
}

5.  Test.java

    @Test
    public void shouldAnswerWithTrue()
    {
        JdkProxy jdkProxy=new JdkProxy();
        UserDao userDao=new UserDaoImpl();
        UserDao userDao1=(UserDao) jdkProxy.createProxy(userDao);
        userDao1.addUserDao();
        System.out.println("\n-----------------------------分割线------------------------------------\n");
        userDao1.deleteUser();
    }

result:

2. CGLIB proxy

     The use of JDK dynamic proxy is very simple, but it has certain limitations (objects using dynamic proxy must implement one or more interfaces). If you want to proxy classes that do not implement interfaces, you can use CGLIB proxy .

         CGLIB (Code Generation Library ) is a high-performance open source code generation package. It uses very low-level bytecode technology to generate a subclass for the specified target class and enhance the subclass. The packages required by CGLIB have been integrated into the core package of the Spring framework, so there is no need to import jar packages in development.

 1.  BookDao.java

package dao;

public class BookDao {
    public void addBook(){
        System.out.println("添加书本");
    }
    public void deleteBook(){
        System.out.println("删除书本");
    }
}

2.  CglibProxy.java

package jdk;


import aspect.MyAspect;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibProxy implements MethodInterceptor {
    //代理方法
    public Object createProxy(Object target){
        Enhancer enhancer=new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        MyAspect myAspect=new MyAspect();
        myAspect.check_permission();
        Object o1=methodProxy.invokeSuper(proxy,args);
        myAspect.log();
        return o1;
    }
}

result:

 

Guess you like

Origin blog.csdn.net/m0_56233309/article/details/123793322