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

匿名 (未验证) 提交于 2019-12-02 21:45:52

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

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

一、javaspringAOPModule

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

三、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/

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!