1. 程式人生 > >Spring中APO切入同類下的其他方法實現事務控制

Spring中APO切入同類下的其他方法實現事務控制

最近在開發中遇到一個問題,當在Service中定義了一個方法並且切入之後,從Controller裡面呼叫該方法可以實現切入,但是當在同一個Service中實現另一方法並呼叫改方法時卻無法切入。程式碼類似於:

  1. /** 
  2.  * Controller 你懂的 
  3. */
  4. publicclass Ctrl {  
  5.  publicvoid ctrl() {  
  6. ......  
  7. service.callMethodA();  
  8. ......  
  9. }  
  10. }  
  11. /** 
  12.  * 業務實現 
  13. */
  14. publicclass Service {  
  15. /** 
  16.  * 被Controller呼叫的方法 
  17.  * 這個方法呼叫被切的方法
     
  18. */
  19.  publicvoid callMethodA() {  
  20. ......  
  21. callMethodB();  
  22. ......  
  23. }  
  24. /** 
  25.  * Aop切入的方法 
  26. */
  27.  publicvoid callMethodB() {  
  28. ......  
  29. }  
  30. }  
  31. /** 
  32.  * AOP的實現 
  33. */
  34. publicclass Aspect {  
  35.  @@AfterReturning("execution(* Service.callMethodB(..))")  
  36.  publicvoid after() {  
  37.  Logger.info("after call and do
     something.");  
  38. }  
  39. }  
總之這樣的呼叫根本不會進去切面,找了很久資料都不知道怎麼回事,果然我還是太弱了。後來有幸得問高人,指點說Service中如此呼叫並非呼叫的是代理類中的方法,是不會被切進去的。換言之,必須要呼叫代理類才會被切進去。 那麼應該怎麼破呢?既然只有呼叫代理類的方法才能切入,那我們拿到代理類不就好了嘛。嘗試性的在IDE裡面搜Aop相關的類,一眼就看到一個叫AopContext的東西,看來遊戲啊,裡面有一個方法叫做currentProxy(),返回一個Object。怎麼樣都要試一下,果斷的把這個object打印出來。報錯了……
  1. java.lang.IllegalStateException: Cannot find current proxy: Set 
    'exposeProxy' property on Advised to 'true' to make it available.  
等等,這個錯有點眼熟,之前傻傻找不到問題的時候看過Spring的配置。
  1. <aop:aspectj-autoproxyproxy-target-class="true"expose-proxy="true"/>
把expose-proxy設成true,再跑一次,終於沒有報錯了,而且打印出了令人欣喜的結果,currentProxy()的結果就是當前Service的代理類,那麼事情簡單了。修改Service的callMethodA()方法如下:
  1. ((Service) AopContext.currentProxy()).callMethodB();  
成功了,方法成功的切入進去了,等下只要再把獲取代理類的方法獨立處理就好了。等等,突然腦洞大開,既然這樣可以,那是不是直接applicationContext.getBean()也可以呢?實驗過後得到的結果是可行,而且配置中的expose-proxy也不用設定成true。 總算這個問題算是解決了,但是以後在方法呼叫的時候就需要謹慎了,感覺應該有更好的辦法解決這個問題,不知道哪位有更好的辦法,能不能告訴我一下下呢?