[Spring] AOP understanding-proxy enhancement

What is AOP

Aspect Oriented Programming, aspect-oriented programming, is a technology that achieves unified maintenance of program functions through pre-compilation and runtime dynamic agents.

AOP is a continuation of OOP and a derivative of functional programming. The use of AOP can isolate (ie decouple) the various parts of the business logic, thereby improving the reusability of the program.

 
 

Functions and advantages

1) During the running of the program, the method is enhanced without modifying the source code

2) Reduce repetitive code, improve development efficiency, and facilitate subsequent maintenance

 
 

Understand AOP thoroughly

Imagine that methods B, C, and D all need to be bound to a method A. We do a mindless reuse (AB, AC, AD). What's the disadvantage of this?

The coupling is too high and it is difficult to modify. If we want to modify a detail of A method, we need to find these three methods (B, C, D) to modify. Therefore, we thought of one of the most simple decoupling ideas-extraction, that is, only the extracted repeated part (A) is called in B, C, and D, so that only one point needs to be modified during modification.

But is A and B, C, and D really completely independent? Is it really completely decoupled?

not at all. After all, A and B (C, D) are still tied together at the code level.
 
The life of a class is divided into three stages-Source source code stage, Class object stage, Runtime runtime stage. We just need to make A and B (C, D) in stage runtime that is bundled together in memory, without the need to source stage to bind together is not it? And the place where we can "hands and feet" is the class object stage .

In the class object stage, the operation of these objects such as Field, Constructor and Method is the essence of reflection. Reflection is the soul of frame design.
 
So far, what exactly is the aspect? These are the methods that have not been bound in the source code stage but have been bound in the runtime stage . For example, AB is an aspect.

The above statement may need to be revised in terms of definition, but it is extremely correct and important in terms of understanding.

 
 

Low-level implementation

The bottom layer of AOP is realized through the dynamic proxy technology provided by Spring.

During operation, Spring uses dynamic proxy technology to dynamically generate proxy objects. When the proxy object method is executed, it performs functional enhancement intervention, and then calls the method of the target object.

There are two commonly used dynamic proxy technologies:

JDK agent based on interface

cglib proxy based on the parent class

Insert picture description here

 
 

JDK proxy

目标类接口 ----------------------------------------------------------------------------------
public interface TargetInterface {
    
    
    public void sayHi();
}


目标类 -------------------------------------------------------------------------------------
public class Target implements TargetInterface {
    
    

    public void sayHi() {
    
    
        System.out.println("目标方法 is runnig...");
    }
}


增强类 -------------------------------------------------------------------------------------
public class Enhance {
    
    

    public void enhanceBefore() {
    
    
        System.out.println("前置增强方法 is running...");
    }

    public void enhanceAfter() {
    
    
        System.out.println("后置增强方法 is running...");
    }
}


代理及其测试 --------------------------------------------------------------------------------
public class SpringTest {
    
    

    @Test
    public void test() {
    
    

        // 目标对象
        final Target target = new Target();

        // 增强对象
        final Enhance enhance = new Enhance();

        // 代理对象
        TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
    
    
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
                        enhance.enhanceBefore();
                        Object invoke = method.invoke(target, args);
                        enhance.enhanceAfter();
                        return invoke;
                    }
                }
        );

        // 代理对象调用方法
        proxy.sayHi();

    }
}

Insert picture description here

 
 

cglib proxy

目标类 -------------------------------------------------------------------------------------
public class Target {
    
    

    public void sayHi() {
    
    
        System.out.println("目标方法 is runnig...");
    }
}


增强类 -------------------------------------------------------------------------------------
public class Enhance {
    
    

    public void enhanceBefore() {
    
    
        System.out.println("前置增强方法 is running...");
    }

    public void enhanceAfter() {
    
    
        System.out.println("后置增强方法 is running...");
    }
}


代理及其测试 --------------------------------------------------------------------------------
public class SpringTest {
    
    

    @Test
    public void test() {
    
    

        // 目标对象
        final Target target = new Target();

        // 增强对象
        final Enhance enhance = new Enhance();

        // 1.创建增强器
        Enhancer enhancer = new Enhancer();
        // 2.设置父类(即目标)
        enhancer.setSuperclass(Target.class);
        // 3.设置回调
        enhancer.setCallback(new MethodInterceptor() {
    
    
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    
    
                enhance.enhanceBefore();
                Object invoke = method.invoke(target, objects);
                enhance.enhanceAfter();
                return invoke;
            }
        });
        // 4.创建代理对象
        Target proxy = (Target) enhancer.create();

        // 代理对象调用方法
        proxy.sayHi();

    }
}

Insert picture description here

Guess you like

Origin blog.csdn.net/m0_46202073/article/details/113878017