天天看點

< 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

轉載于:https://www.cnblogs.com/woftlcj/p/9988254.html