今天看项目源码,看到Service类继承了一个SelfProxy类,这个类实现了一个叫self()的方法,用于返回动态代理生成的实例。java
为何要返回实例呢,由于有的时候类内部须要调用自身的public方法,而这些方法有些是带着advice的,直接调用advice不会生效。this
不生效的缘由顾名思义,JDK动态代理是运行期创造代理实例的,那么在该service类外部,你们都是经过代理类实例在访问,可是在内部,仍是没有通过advice的原实例,代理
这就意味着,JDK生成的动态代理,在内部和外部有一个夹层,advice的活是在这个夹层干的,那么很遗憾的,这个问题无解,只能经过在内部拿到外层代理实例的引用来调用自身方法。继承
然而我ctrl+f了一部分代码,发现很多直接this.xx的调用,甚至还在调用带事务控制advice的方法。这很危险。事务
Let the sleeping dog sleep,毕竟有可能那些方法真的在业务上不须要advice也能跑吧。源码
若是不使用JDK动态代理,上述问题就不会发生了。无论是Spring自己支持的CGLib,仍是说AspectJ。编译
再往深刻想,JDK动态代理的意义究竟是什么呢,为何不提供一种,编译期的代理机制呢,毕竟第三方方案都好几种了。service
我以为仍是非动态代理稳一些,不过再话句话想一想,非动态代理,和宏,和template,就太像了。引用
只在源码级别搞事情,不够酷,不够java,咱们必定要RUNTIME。方法
但愿哪天Spring能想办法绕开这个事情吧。