Spring5 source code analysis-------Aop (two)

The code address
spring04
thinks that the blogger can also give a Star

Before we look at the five notification execution source code, let's first understand the core issues. The core design patterns of SpringAop are dynamic agent pattern and responsibility chain design pattern. Dynamic agents have also been mentioned before, cglib and jdk agents. As for the chain of responsibility model, it is the key content this time. He is related to the orderly execution of our five notices.
Project structure:
Insert picture description here

Let's first simulate the chain of responsibility model. The core of the chain of responsibility design model is the idea of ​​recursion, but recursion will cause overflow, so we need constraints to make the program run normally. In the following program, in addition to changing the front and surrounding notifications In addition to the order of addition, other methods will not cause the result to change.
This simulation is not a complete AOP five notification normal sequence simulation. For why the surround notification appears in the first one, you can check the sortAdvisors method of AspectJAwareAdvisorAutoProxyCreator . After the enhancement, an internal sorting was made as
to why the position of "after surrounding notification" was incorrect, because its internal has undergone certain changes, and it is different from several other notifications. We will conduct a detailed interpretation next time.
AfterInterceptor.java

package com.interceptor.impl;

import com.interceptor.MethodInterceptor;
import com.invocation.MethodInvocation;

import java.lang.reflect.InvocationTargetException;

public class AfterInterceptor implements MethodInterceptor {
    
    
    @Override
    public void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException {
    
    
        methodInvocation.process();
        System.out.println("后置通知");
    }
}

AroundInterceptor.java

package com.interceptor.impl;

import com.interceptor.MethodInterceptor;
import com.invocation.MethodInvocation;

import java.lang.reflect.InvocationTargetException;

public class AroundInterceptor implements MethodInterceptor {
    
    
    @Override
    public void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException {
    
    
        System.out.println("环绕通知之前");
        methodInvocation.process();
        System.out.println("环绕通知之后");
    }
}

BeforeInterceptor.java

package com.interceptor.impl;

import com.interceptor.MethodInterceptor;
import com.invocation.MethodInvocation;

import java.lang.reflect.InvocationTargetException;

public class BeforeInterceptor implements MethodInterceptor {
    
    
    @Override
    public void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException {
    
    
//        methodInvocation.process();
        System.out.println("前置通知");
        methodInvocation.process();
    }
}

MethodInterceptor.java

package com.interceptor;


import com.invocation.MethodInvocation;

import java.lang.reflect.InvocationTargetException;

public interface MethodInterceptor {
    
    
    /**
     * 通知共用接口
     */
    public void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException;
}

DefaultMethodInvocation.java

package com.invocation.impl;

import com.interceptor.MethodInterceptor;
import com.invocation.MethodInvocation;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class DefaultMethodInvocation implements MethodInvocation {
    
    

    ArrayList<MethodInterceptor> methodInterceptorArrayList;

    static int index;

    Method method;

    Object object;

    public DefaultMethodInvocation(ArrayList<MethodInterceptor> methodInterceptorArrayList, Method method, Object object) {
    
    
        this.methodInterceptorArrayList = methodInterceptorArrayList;
        this.method = method;
        this.object = object;
    }

    public DefaultMethodInvocation(ArrayList<MethodInterceptor> methodInterceptorArrayList) {
    
    
        this.methodInterceptorArrayList = methodInterceptorArrayList;
    }

    @Override
    public void process() throws InvocationTargetException, IllegalAccessException {
    
    
        if(index == methodInterceptorArrayList.size()){
    
    
            //执行目标方法
            method.invoke(object);
            return;
        }
        //调用添加进去的通知
        MethodInterceptor methodInterceptor = methodInterceptorArrayList.get(index);
        index++;
        methodInterceptor.invoke(this);
        //递归循环调用
//        process(this);
    }
}

MethodInvocation.java

package com.invocation;

import com.interceptor.MethodInterceptor;

import java.lang.reflect.InvocationTargetException;

public interface MethodInvocation {
    
    
    /**
     * 调用链的形成
     */
    void process() throws InvocationTargetException, IllegalAccessException;
}

UserService.java

package com.service;

public class UserService {
    
    
    public void add(){
    
    
        System.out.println("addUserService");
    }
}

Application.java

package com;

import com.interceptor.MethodInterceptor;
import com.interceptor.impl.AfterInterceptor;
import com.interceptor.impl.AroundInterceptor;
import com.interceptor.impl.BeforeInterceptor;
import com.invocation.impl.DefaultMethodInvocation;
import com.service.UserService;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class Application {
    
    
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    
    
        ArrayList<MethodInterceptor> methodInterceptorList = new ArrayList<>();
        methodInterceptorList.add(new AroundInterceptor());
        methodInterceptorList.add(new BeforeInterceptor());
//        methodInterceptorList.add(new AroundInterceptor());
        methodInterceptorList.add(new AfterInterceptor());

        UserService userService = new UserService();
        Method loginMethod = UserService.class.getMethod("add");
        new DefaultMethodInvocation(methodInterceptorList,loginMethod,userService).process();
    }
}

Guess you like

Origin blog.csdn.net/weixin_43911969/article/details/114108627