< aop:aspect>與< aop:advisor>的區別
轉載地址:https://blog.csdn.net/u011983531/article/details/70504281
用< aop:advisor>。那麼,對於< aop:aspect>與< aop:advisor>的區別,具體是怎樣的呢?
至於兩者的區別,網上有很多資料,但是似乎都不能說清楚。
首先,我們需要明確兩者的概念。
< aop:aspect>:定義切面(切面包括通知和切點)
< aop:advisor>:定義通知器(通知器跟切面一樣,也包括通知和切點)
下面,我們列舉兩者的幾個區別。
1、實現方式不同
< aop:aspect>定義切面時,只需要定義一般的bean就行,而定義< aop:advisor>中引用的通知時,通知必須實現Advice介面。
下面我們舉例說明。
首先,我們定義一個介面Sleepable和這個介面的實現Human,程式碼如下:
public interface Sleepable { public void sleep(); } public class Human implements Sleepable { @Override public void sleep() { System.out.println("我要睡覺了!"); } }
下面是< aop:advisor>的實現方式:
//定義通知 public class SleepHelper implements MethodBeforeAdvice,AfterReturningAdvice{ @Override public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable { System.out.println("睡覺前要脫衣服!"); } @Override public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable { System.out.println("起床後要穿衣服!"); } } //aop配置 <bean id="sleepHelper" class="com.ghs.aop.SleepHelper"></bean> <aop:config> <aop:pointcut expression="execution(* *.sleep(..))" id="sleepPointcut"/> <aop:advisor advice-ref="sleepHelper" pointcut-ref="sleepPointcut"/> </aop:config> <bean id="human" class="com.ghs.aop.Human"/>
下面是< aop:aspect>的實現方式:
//定義切面 public class SleepHelperAspect{ public void beforeSleep(){ System.out.println("睡覺前要脫衣服!"); } public void afterSleep(){ System.out.println("起床後要穿衣服!"); } } //aop配置 <bean id="sleepHelperAspect" class="com.ghs.aop.SleepHelperAspect"></bean> <aop:config> <aop:pointcut expression="execution(* *.sleep(..))" id="sleepPointcut"/> <aop:aspect ref="sleepHelperAspect"> <!--前置通知--> <aop:before method="beforeSleep" pointcut-ref="sleepPointcut"/> <!--後置通知--> <aop:after method="afterSleep" pointcut-ref="sleepPointcut"/> </aop:aspect> </aop:config> <bean id="human" class="com.ghs.aop.Human"/>
測試程式碼如下:
public class TestAOP { public static void main(String[] args) { method1(); // method2(); } private static void method1() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext1.xml"); Sleepable sleeper = (Sleepable) context.getBean("human"); sleeper.sleep(); } private static void method2() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext2.xml"); Sleepable sleeper = (Sleepable) context.getBean("human"); sleeper.sleep(); } //執行結果 睡覺前要脫衣服! 我要睡覺了! 起床後要穿衣服! }
2、使用場景不同
< aop:advisor>大多用於事務管理。
例如:
<!-- 會重複讀,不會髒讀事務 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*" timeout="120" propagation="REQUIRED" rollback-for="Exception" /> </tx:attributes> </tx:advice> <aop:config proxy-target-class="true"> <aop:pointcut id="txPointCut" expression="..."/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut" /> </aop:config>
< aop:aspect>大多用於日誌,快取
其實,不管是< aop:advisor>還是< aop:aspect>最終的實現邏輯是一樣的。
小結:
可以看出,< aop:advisor>和< aop:aspect>其實都是將通知和切面進行了封裝,原理基本上是一樣的,只是使用的方式不同而已。
附:
下面推薦幾篇博文。
http://www.iteye.com/problems/69785
http://blog.sina.com.cn/s/blog_5198c7370100hw1p.html
http://blog.csdn.net/huitoukest/article/details/46469177
http://www.tz365.cn/ask/shenghuo/2016/0804/739237.html
https://zhidao.baidu.com/question/371238289198208804.html