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

本文详细解析了Spring AOP在调用代理对象时的内部机制,包括如何通过invoke方法处理增强器,如何根据拦截器链顺序执行BeforeAdvice、目标方法和AfterAdvice。核心在于递归调用的实现,利用动态代理和责任链模式确保切面的正确执行顺序。文章还提供了一张增强器调用流程图以帮助理解。
摘要由CSDN通过智能技术生成

一:调用AOP 代理对象

本章结合源码讲解AOP的代理对象创建完成是如何调用的。

1,调用AOP代理类的方法

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

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

 

2,invoke方法

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

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

2,oldProxy = AopContext.setCurrentProxy(proxy);

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

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

 

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用了一个非常巧妙的设计方式-------递归。

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

 

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

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

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

 

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

 

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

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

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

 

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

 

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

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

 

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

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

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

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

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

 

PS:获取一线最新架构面试资料:345353515 

关注微信图灵学院公众号



回复:“阿里手册”免费下载阿里巴巴开发手册!
回复:“架构学习”了解最新知识!
【精选面试题】回复“面试”得到各大互联网公司精选面试!
【JAVA架构资料】回复“架构资料”即可获取!
【双十一架构高清体系图】回复“架构图”即可获取!
【经典书籍】回复“书籍”即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值