本節中,咱們經過具體的實例說明基於CGLib字節碼動態代理沒法享受Spring AOP事務加強的特殊方法。 java
package com.baobaotao.special; import org.springframework.stereotype.Service; @Service("userService") public class UserService { //① private方法因訪問權限的限制,沒法被子類覆蓋 private void method1() { System.out.println("method1"); } //② final方法沒法被子類覆蓋 public final void method2() { System.out.println("method2"); } //③ static是類級別的方法,沒法被子類覆蓋 public static void method3() { System.out.println("method3"); } //④ public方法能夠被子類覆蓋,所以能夠被動態字節碼加強 public void method4() { System.out.println("method4"); } }
Spring經過CGLib動態代理技術對UserService Bean實施AOP事務加強的關鍵配置,具體以下所示: mysql
… <aop:config proxy-target-class="true"><!-- ①顯式使用CGLib動態代理 --> <!-- ②但願對UserService全部方法實施事務加強 --> <aop:pointcut id="serviceJdbcMethod" expression="execution(* com.baobaotao.special.UserService.*(..))"/> <aop:advisor pointcut-ref="serviceJdbcMethod" advice-ref="jdbcAdvice" order="0"/> </aop:config> <tx:advice id="jdbcAdvice" transaction-manager="jdbcManager"> <tx:attributes> <tx:method name="*"/> </tx:attributes> </tx:advice> …
在①處,咱們經過proxy-target-class="true"顯式使用CGLib動態代理技術,在②處經過AspjectJ切點表達式表達UserService全部的方法,但願對UserService全部方法都實施Spring AOP事務加強。
在UserService添加一個可執行的方法,以下所示:spring
package com.baobaotao.special; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Service; @Service("userService") public class UserService { … public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("user/special/applicationContext.xml"); UserService service = (UserService) ctx.getBean("userService"); System.out.println("before method1"); service.method1(); System.out.println("after method1"); System.out.println("before method2"); service.method2(); System.out.println("after method2"); System.out.println("before method3"); service.method3(); System.out.println("after method3"); System.out.println("before method4"); service.method4(); System.out.println("after method4"); } }
在運行UserService以前,將Log4J日誌級別設置爲DEBUG,運行以上代碼查看輸出日誌,以下所示:sql
序 號 |
動態代理策略 |
不能被事務加強的方法 |
1 | 基於接口的動態代理 | 除public外的其餘全部的方法,此外public static也不能被加強 |
2 | 基於CGLib的動態代理 | private、static、final的方法 |