Spring5源码分析-------Aop篇(二)

代码地址
spring04
觉得博主还可以给个Star

在我们看五个通知执行源码之前,我们先来了解一下核心问题。SpringAop核心的设计模式为,动态代理模式和责任链设计模式。动态代理前面也提到过,cglib和jdk代理。至于责任链模式才是这一次的重点内容。他关系到我们五个通知为什么会有序的执行。
项目结构:
在这里插入图片描述

我们先来模拟一下责任链模式,责任链设计模式核心是递归的思路,但是递归会产生溢出的现象,所以我们需要约束条件,使程序正常运行.在以下程序中,除了更改前置和环绕通知的添加顺序之外,其他的方式均不会导致结果的变化.
此模拟不是完整的AOP五个通知正常顺序模拟,针对于环绕通知为何出现在第一个,可以查看AspectJAwareAdvisorAutoProxyCreator的sortAdvisors方法,在获取到增强之后,内部进行了一个排序
对于为何"环绕通知之后"位置不正确,是因为它的内部进行了一定的变化,和其他几个通知有出入.我们下次进行详细的解读.
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();
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43911969/article/details/114108627