一般來講Spring AOP有兩種代理方式,一種默認的JDK代理,只能代理接口,一種是CGLIB代理,能夠代理具體的類對象。java
SpringAOP默認爲對AOP代理使用標準的JDK動態代理。若是業務對象不實現接口,則使用CGLIB。git
若是使用CGLIB,要注意對於CGLIB,不能advice final方法,由於它們不能在運行時生成的子類中被重寫。github
因爲Spring的AOP框架基於代理的特性,根據定義,目標對象內的方法調用不會被攔截。對於JDK代理,只能截獲對代理的公共接口方法調用。使用cglib,能夠截獲代理上的公共和受保護的方法調用(若是須要,甚至能夠截獲包可見的方法)。spring
若是須要攔截在目標類內的方法調用甚至構造函數,那麼考慮使用Spring驅動的native AspectJ weaving,而不是Spring的基於代理的AOP框架。框架
要強制使用CGLIB代理,請將aop:config元素的proxy target class屬性的值設置爲true,以下所示:函數
<aop:config proxy-target-class="true">
<!-- other beans defined here... -->
</aop:config>
複製代碼
要在使用@Aspectj auto proxy支持時強制cglib代理,請將aop:aspectj-autoproxy元素的proxy-target-class屬性設置爲true,以下所示:this
<aop:aspectj-autoproxy proxy-target-class="true"/>
複製代碼
SpringAOP是基於代理的,那什麼是代理呢?spa
首先咱們考慮一個最簡單的POJO對象:代理
public class SimplePojo implements Pojo {
public void foo() {
// this next method invocation is a direct call on the 'this' reference
this.bar();
}
public void bar() {
// some logic...
}
}
複製代碼
若是直接調用該對象的方法,則運行原理以下所示:code
調用方法以下:
public class Main {
public static void main(String[] args) {
Pojo pojo = new SimplePojo();
// this is a direct method call on the 'pojo' reference
pojo.foo();
}
}
複製代碼
若是是調用代理,則運行原理以下:
調用方法以下:
public class Main {
public static void main(String[] args) {
ProxyFactory factory = new ProxyFactory(new SimplePojo());
factory.addInterface(Pojo.class);
factory.addAdvice(new RetryAdvice());
Pojo pojo = (Pojo) factory.getProxy();
// this is a method call on the proxy!
pojo.foo();
}
}
複製代碼
本文的例子請參考aop-proxy
更多教程請參考 flydean的博客