springAOP五个通知消息调用链的原理

2019-08-16 10:10:49来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

springAOP五个通知消息调用链的原理

以下是以项目的的形式就行运行验证五个消息的运行顺序及调用链的原理,里面主要用到了递归调用。

本篇博客先给大家展示代码,后面进行文字及图片讲解执行的顺序

一、创建java项目springAOPModule

二、创建项目包结构如下:

三、创建目标方法UserService

/**
 * 目标调用类
 */
public class UserService {

    public void login(String userName,Integer age){
        System.out.println("姓名为:"+userName+",年龄为:"+age);
    }
}

  

四、创建执行接口及方法(MethodInvocation/DefaultMethodInvacation)

1、方法执行接口:MethodInvocation

/**
 * 方法执行接口
 */
public interface MethodInvocation {
    Object process() throws InvocationTargetException, IllegalAccessException;
}

  

2、方法执行实习类:DefaultMethodInvacation

/**
 * 执行方法实现类
 */
public class DefaultMethodInvacation implements MethodInvocation {
    //5个通知集合
    private List<MethodInterceptor> chian;
    //目标对象
    private Object target;
    private Method method;// 目标方法
    private Object args[];// 目标参数
    int currentChianIndex;// 记录当前拦截器链调用指针

    public DefaultMethodInvacation(List<MethodInterceptor> chian, Object target, Method method, Object[] args) {
        this.chian = chian;
        this.target = target;
        this.method = method;
        this.args = args;
    }

    @Override
    public Object process() throws InvocationTargetException, IllegalAccessException {

        if(currentChianIndex==chian.size()){
            return method.invoke(target,args);
        }
        MethodInterceptor methodInterceptor = chian.get(currentChianIndex++);
        return methodInterceptor.invoke(this);
    }
}

  

五、创建拦截接口及方法

1、目标方法拦截接口:MethodInterceptor

/**
 * 创建方法拦截接口
 */
public interface MethodInterceptor {
    //执行通知的拦截
    Object invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException;
}

  2、前置通知方法

/**
 * 前置方法
 */
public class BeforInterceptorImpl implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException {
        System.out.println("进入前置通知");
        return  methodInvocation.process();
    }
}

  3、后置通知方法

public class AfterMethodInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInterceptor) throws InvocationTargetException, IllegalAccessException {
        Object process = methodInterceptor.process();
        System.out.println("后置通知");
        return process;
    }
}

  4、环绕通知方法

public class AroundMethodInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException {
        System.out.println("环绕通知之前执行....");
        Object process = methodInvocation.process();
        System.out.println("环绕通知之后执行....");
        return process;
    }
}

  六、创建测试方法execute

public class execute {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        ArrayList<MethodInterceptor> list = new ArrayList<>();
        list.add(new BeforInterceptorImpl());
        list.add(new AfterMethodInterceptor());
        list.add(new AroundMethodInterceptor());
        UserService userService = new UserService();
        Method logingMethod = UserService.class.getMethod("login",String.class,Integer.class);
        Object[] objects ={"cyb",25};
        new DefaultMethodInvacation(list,userService,logingMethod,objects).process();
    }
}

  七、运行效果:

八、运行步骤原理解析:

启动运行时,系统运行步骤如下:

1、将前置通知、后置通知、环绕通知3个拦截方法放入集合中

2、获取目标方法

3、创建目标方法中的参数

4、通过有参构造方法将拦截方法集合、目标方法和参数传递到执行方法中并调用process处理方法

5、process方法中,第一次获取拦截方法中第一个前置通知,并在里面继续调用process方法,此时index下标为1,获取后置拦截方法,并在该方法中继续调用process,此时又获取的是环绕通知拦截方法,再次进入环绕通知方法,打印”环绕通知之前执行。。。”语句,此时index值为:3,再次调用process方法,此时index等于集合长度,调用模板方法,则打印目标方法语句。调完后继续打印环绕方法的”环绕通知之后执行。。。”,执行完后在方法继续返回到后置方法执行打印“后置通知”语句

九、图形讲解

注意:前置方法的打印要写在方法调用之前,后置方法打印要写在调用方法之后,环绕方法打印则分别写在调用方法前后。

以上是本人对spring aop5个通知调用链原理的讲解,大家理解后可以对这进行更好的优化,若上文有不合适的欢迎各位博友讨论。转发请说明出处,本人博客主页地址为:https://home.cnblogs.com/u/chenyuanbo/

 


原文链接:https://www.cnblogs.com/chenyuanbo/p/11167459.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:集合(一)

下一篇:spring5 源码深度解析— IOC 之 bean 的初始化