SpringAOP的一個問題

問題:項目中用到了AOP方式記錄日誌,對於所有create開頭的方法全部做了攔截。現在有一個類,裏面有createFile方法和newFolder方法,newFolder方法裏面會調用到createFile方法,但此時,createFile的攔截記錄日誌卻起不到作用,這是爲什麼呢。

緣由:Spring的AOP實現方式有兩種:Java動態代理和Cglib動態增強,這兩種方式在Spring中是可以無縫自由切換的。Cglib方式增強的AOP目標類,會創建兩個對象,一個是Bean實例本身,一個是Cglib增強代理對象。Spring通過AopProxy接口,抽象了這兩種實現,實現了一致的AOP方式。但是這種抽象帶了一個缺陷,那就是扼殺了Cglib能夠直接創建普通類的增強子類的能力,Spring相當於把Cglib動態生成的子類,當普通的代理類了。回到問題上就是:newFolder方法經過AopProxy給過濾掉,方法內部調用createFile,雖然配置了方法攔截,但是因爲是內部調用,AopProxy感知不到,因此攔截日誌起不到作用。

延伸:這個問題,可以延伸到同樣AOP性質的聲明式事務。如果createFile配置了事務,但是newFolder沒有配置,同理,newFolder方法內的createFile並不會開啓事務,假設createFile被調用了3次,第三次產生錯誤,事務並不能正常的回滾了。因此可以認爲:[color=red]內部調用時,被調用方法的事務聲明將不起作用;同樣事務的傳播策略在內部方法調用時將不起作用[/color]

解決:這個東西我沒想到什麼好方法改變,只能避開Spring目前的AOP實現上的限制,要麼都聲明要事務,要麼分開成兩個類,要麼直接在方法裏使用編程式事務。
發佈了19 篇原創文章 · 獲贊 0 · 訪問量 2929
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章