Spring AOP實現方式
阿新 • • 發佈:2019-02-08
Spring 實現AOP有兩種方式, JDK動態代理和CGLIB代理,Spring會根據攔截物件來選擇何種實現。
如果攔截物件至少實現了一個介面,則會使用JDK動態代理,所有改目標類實現的介面都將被代理。
如果攔截物件沒有實現任何介面,則會建立一個CGLIB代理。
如果你的目標物件實現了介面而有JDK動態代理實現,那麼你將得到一個proxy類,這個proxy類是無法轉換成目標類的。
package springaop; import org.springframework.stereotype.Component; public interface Performance { void perform(); }
package springaop; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.stereotype.Component; @Component public class DanceParty implements Performance {// public void perform() { // TODO Auto-generated method stub System.out.println("Dance Party"); //return 0; } }
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DanceAspectConfig.class);
DanceParty dance = (DanceParty)context.getBean("danceParty");
當你從context獲取 DanceParty後,強制轉換成目標物件時是會報錯的,因為JDK實現了一個代理類返回給你。
Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy16 cannot be cast to springaop.DanceParty
at springaop.DanceMain.main(DanceMain.java:13)
如果用CGLIB實現,這個強制轉換是可以的。你可以強制使用CGLIB來實現Spring的 AOP 在@EnableAspectJAutoProxy(proxyTargetClass=true)
或者在xml里加入 <aop:aspectj-autoproxy
proxy-target-class="true"/>
更多的坑和經驗詳見Spring AOP各種討論