AOP的第一個小坑

今天看項目源碼,看到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能想辦法繞開這個事情吧。

相關文章
相關標籤/搜索