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配置
//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>其实都是将通知和切面进行了封装,原理基本上是一样的,只是使用的方式不同而已。

作者:爱上香锅的麻辣
原文:https://blog.csdn.net/u011983531/article/details/70504281

猜你喜欢

转载自blog.csdn.net/q503385724/article/details/85615842