likes
comments
collection
share

Spring Aop 到底做了什么?

作者站长头像
站长
· 阅读数 15

最近几天在工作中遇到了一个动态代理所带来的坑,遂简单的研究了一波aop执行流程的源码,希望对各位有所帮助。

对于AOP执行顺序不清楚的jym,可以看一下这篇文章:Spring AOP 执行顺序问题

文章结构

本文想以一个问题提出AOP动态代理的问题,通过问题的思考,以一个简单的例子来解读Spring AOP大致做了什么,最后再做一波总结。

简单的问题

简单的切面类

Spring Aop 到底做了什么?

简单的代理类

Spring Aop 到底做了什么?

问题其实很简单,this.dy2()会不会走切面,打印出before?

答案是:不会

答案有些朋友有可能答对了,但是为什么呢?

我当时错误的思考是,controller对象已经是cglib动态代理的对象了,也就是增强对象了,dy()方法走切面肯定是不会有问题的,但是为什么dy2()不走切面呢?this对象不是已经代理过的增强的controller么,那么dy2()方法应该也是增强的,必然也会走切面,为什么最后却不走切面呢?

思考中。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

解答:首先一开始就已经搞错了,this对象增强后的controller对象本来就不是同一个对象,this对象只是controller对象本身。你可以直接从spring容器中获取增强后的controller然后与this进行对比就会发现他们并不是同一个对象。

Spring Aop 到底做了什么?

为什么会这样呢?

简单的源码分析

在这里我只会做关键地方和本文有关的源码解读,以后我会写一篇详细的Spring AOP执行流程的源码分析Spring创建动态代理源码分析

Spring AOP 创建动态代理源码分析

Spring AOP 动态代理执行流程源码分析

首先Spring的AOP采用的动态代理是jdkcglib

对应的接口是AopProxy,对应的类是CglibAopProxyJdkDynamicAopProxy

Spring Aop 到底做了什么?

本文以CglibAopProxy来做相关分析。

Spring Aop 到底做了什么?

这个方法里面的东西很多,以及后续的涉及东西也会很多,所以我会直接定位到最关键的地方忽略掉很多东西,只是为了定位到反射掉用自己类的地方,然后证明所谓的切面也就是一层一层的执行对应的增强方法,最后反射再掉用自己的实际方法,所以这就证明了一点那就是上述controller中的this其实就是它本身的而不是增强的对象。

Spring Aop 到底做了什么?

Spring Aop 到底做了什么?

Spring Aop 到底做了什么?

target为什么是未增强的对象呢?这要涉及到bean动态代理的源码,我也大致截一下图方便理解。

Spring Aop 到底做了什么?

Spring Aop 到底做了什么?

Spring Aop 到底做了什么?

Spring Aop 到底做了什么?

Spring Aop 到底做了什么?

总结

源码的分析十分的粗糙,但也只是为了证明 不管是jdk还是cglib动态代理确实是动态生成了代理类,但是代理类执行增强方法的时候只是判断是否有切面,然后按照切面顺序执行切面方法,最后通过反射来调用实际方法,而反射的对象确是原本的对象而不是增强后的代理对象。

非常感谢能看到这里的JYM,如果本文有误请不吝赐教。

Spring Aop 到底做了什么?