AOP的第一个小坑
Posted user-for-once
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AOP的第一个小坑相关的知识,希望对你有一定的参考价值。
今天看项目源码,看到Service类继承了一个SelfProxy类,这个类实现了一个叫self()的方法,用于返回动态代理生成的实例。
为什么要返回实例呢,因为有的时候类内部需要调用自身的public方法,而这些方法有些是带着advice的,直接调用advice不会生效。
不生效的原因顾名思义,JDK动态代理是运行期创造代理实例的,那么在该service类外部,大家都是通过代理类实例在访问,但是在内部,还是没有经过advice的原实例,
这就意味着,JDK生成的动态代理,在内部和外部有一个夹层,advice的活是在这个夹层干的,那么很遗憾的,这个问题无解,只能通过在内部拿到外层代理实例的引用来调用自身方法。
然而我ctrl+f了一部分代码,发现不少直接this.xx的调用,甚至还在调用带事务控制advice的方法。这很危险。
Let the sleeping dog sleep,毕竟有可能那些方法真的在业务上不需要advice也能跑吧。
如果不使用JDK动态代理,上述问题就不会发生了。不管是Spring本身支持的CGLib,还是说AspectJ。
再往深入想,JDK动态代理的意义到底是什么呢,为什么不提供一种,编译期的代理机制呢,毕竟第三方方案都好几种了。
我觉得还是非动态代理稳一些,不过再话句话想想,非动态代理,和宏,和template,就太像了。
只在源码级别搞事情,不够酷,不够java,我们一定要RUNTIME。
希望哪天Spring能想办法绕开这个事情吧。
以上是关于AOP的第一个小坑的主要内容,如果未能解决你的问题,请参考以下文章