您的位置 首页 java

Java互联网架构-Spring源码分析深入浅出AOP

欢迎关注头条号:java小马哥

周一至周日早九点半!下午三点半!精品技术文章准时送上!!!

精品学习资料获取通道,参见文末

一:调用 AOP 代理对象

1,调用AOP代理类的方法

假设Calculate类是切点,里面有一个add方法。此时执行Calculate.add的方法的时候直接进入JdkDynamicAopProxy类中的invoke方法。

2,invoke方法

不用想在调用到这里的时候肯定是invoke的方法对增强器进行调用,那么看看它都做了什么事情。

1,判断equals、 hashcode 、.getDeclaringClass()、advised.opaque这些个东东都不进行代理调用。

2,oldProxy = AopContext.setCurrentProxy(proxy);

这句话的意识是说要不要暴露我的代理对象。举个例子:它就是处理@EnableAspectJAutoProxy(exposeProxy = true)。处理exposeProxy = true的。如果为true就进行暴露。3

3,this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass)

获取拦截器链,将获取到的方法的切面,转化为拦截器链。通过getInterceptorsAndDynamicInterceptionAdvice方法从 缓存 拿,拿不到通过该方法进行解析再放入缓存

4,chain. isEmpty ()

判断是否为空如果为空直接进行反射调用,通过invokeJoinpointUsingReflection进行反射调用。

5,ReflectiveMethodInvocation

创建一个反射的方法调用,创建一个对象

6,invocation.proceed()最最最最重要的方法;AOP的核心思想就在这个方法里。

这里面有个小的 算法 this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() – 1 递归调用 。currentInterceptorIndex初始值-1,我们知道走到这里的时候正常去掉我们的目标方法。但是调用目标方法不是随便调用的,而是有顺序的,在上面,将代理的切面转换成拦截器链的时候,进行了排序,下面看一张图,是增强器的执行流程。由图可知,前置方法最先执行,然后目标方法,然后后置方法,返回通知和异常通知只能执行一个。所以在这里面Spring用了一个非常巧妙的设计方式——-递归。

7,递归调用执行增强器如下图

如图可知,currentInterceptorIndex 初始值是1,this.interceptorsAndDynamicMethodMatchers.size() 这是增强器的总数。如果这个表达式成立的时候,才调用目标方法。当currentInterceptorIndex==-1的时候。不相等就往下走。走到((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this)。这里是动态代理调用。this,代表当前类的引用。第一次进来的时候又执行了一次proceed方法。

8,(MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this)

当第二次调用回来的时候currentInterceptorIndex 变为0,执行下标为1的拦截器。调用了异常增强器。然后走到invoke方法进去看下,如第二个如所知,如果抛异常才调用invokeAdviceMethod方法。所以这里不进行拦截。接着往后看。

9,currentInterceptorIndex ==3的时候。直接进入invoke方法中,可以看到如下图的方法,如图可知before方法先执行了。然后又回到proceed方法。此时currentInterceptorIndex ==4.正好满足条件可以执行目标发放,此时打印目标方法信息。此时执行完以后。回退到之前未执行完的递归调用。以此类推。最后退出。此时,增强器调用完毕。

总结:总结一下AOP的增强器调用的核心思想。

1:在把增强器转化成拦截器链的时候,对切面进行了排序。根据执行的顺序可知,before方法,总是在目标方法前面的一个位置。但是调用的时候是最后调用的。但是,通过代码断点可知,最后执行的,最先被打印,以此类推,也就是说,最先执行的,确实最后被真正的调用。从前调用,从后执行。

2:使用了动态代理模式和 责任链模式 ,通过责任链去递归调用动态代理的invoke方法,执行不同的切面,然后又都调用proceed方法进行递归

3:BeforeAdvice总是在目标方法执行之前调用。通过currentInterceptorIndex==his.interceptorsAndDynamicMethodMatchers.size() -1的算法。

4:最后附赠一张,增强器的调用流程图。

封面图源网络,侵权删除)

私信头条号,发送:“资料”,获取更多“秘制” 精品学习资料

如有收获,请帮忙转发,您的鼓励是作者最大的动力,谢谢!

一大波微服务、分布式、高并发、高可用的原创系列文章正在路上,

欢迎关注头条号:java小马哥

周一至周日早九点半!下午三点半!精品技术文章准时送上!!!

十余年BAT架构经验倾囊相授

文章来源:智云一二三科技

文章标题:Java互联网架构-Spring源码分析深入浅出AOP

文章地址:https://www.zhihuclub.com/192846.shtml

关于作者: 智云科技

热门文章

网站地图