技术栈

四、(一)使用XML配置AOP

2019-07-03  本文已影响0人  烟雨乱平生

环境

目标类
public class Dog implements Animal {
    @Override
    public void run() {
        System.out.println("dog run");
    }

    @Override
    public void sleep() {
        System.out.println("dog sleep");
    }
}

注入bean

<bean id="dog" class="pray.wang.xml.entity.support.Dog"></bean>
切面类
public class LogAspect {

    public void start(){
        System.out.println("start invoke method");
    }

    public void end(){
        System.out.println("end invoke method");
    }

    public void ret(){
        System.out.println("invoke method return");
    }

    public void thr(){
        System.out.println("invoke method error");
    }
}

注入bean

<bean id="logAspect" class="pray.wang.xml.aspect.LogAspect"></bean>

声明切面

要求
  1. 导入aop命名空间。
  2. 在Bean的配置文件中,配置切面的Bean,必须要有id属性,供<aop:aspect>元素引用。
  3. 在Bean的配置文件中,所有Spring AOP的配置都必须定义在<aop:config>元素内部。
  4. 在<aop:config>元素内部,定义一个<aop:aspect>元素来声明切面,用其ref属性指定切面的Bean。
示例
<bean id="logAspect" class="pray.wang.xml.aspect.LogAspect"></bean>
<aop:config>
    <aop:aspect ref="logAspect"></aop:aspect>
</aop:config>

声明切入点

要求
  1. 必须在<aop:config>元素 或 <aop:aspect>元素下,使用<aop:pointcut>元素声明。
    a. 如果声明在<aop:config>下,对<aop:config>下所有切面有效.
    b. 如果声明在<aop:aspect>下,只对当前切面有效。
  2. 基于XML声明的AOP,不允许在切入点表达式中,用名称引用其他表达式。
示例
<aop:config>
    <aop:pointcut id="sleep" expression="execution(* pray.wang.xml..Dog.*(..))"></aop:pointcut>
    <aop:aspect ref="logAspect"></aop:aspect>
</aop:config>
<aop:config>
    <aop:aspect ref="logAspect">
        <aop:pointcut id="sleep" expression="execution(* pray.wang.xml..Dog.*(..))"></aop:pointcut>
    </aop:aspect>
</aop:config>

声明切面的通知

要求
  1. 通知声明在<aop:aspect>元素下,每种通知对应一个XML元素。
    a. 前置通知:<aop:before>
    b. 后置通知:<aop:after>
    c. 返回通知:<aop:after-returning>
    d. 异常通知:<aop:after-throwing>
    e. 环绕通知:<aop:around>
  2. method属性指定切面中的通知方法的名称,pointcut-ref 指向<aop:pointcut>元素的id属性。
示例
<aop:config>
    <aop:aspect ref="logAspect">
        <aop:before method="start" pointcut="execution(* pray.wang.xml..*.run(..))"></aop:before>
        <aop:after method="end" pointcut="execution(* pray.wang.xml..*.run(..))"></aop:after>
        <aop:after-returning method="ret" pointcut="execution(* pray.wang.xml..*.run(..))"></aop:after-returning>
        <aop:after-throwing method="thr" pointcut="execution(* pray.wang.xml..*.run(..))"></aop:after-throwing>
    </aop:aspect>
</aop:config>
<aop:config>
    <aop:aspect ref="logAspect">
        <aop:pointcut id="sleep" expression="execution(* pray.wang.xml..Dog.*(..))"></aop:pointcut>
        <aop:before method="start" pointcut-ref="sleep"></aop:before>
        <aop:after method="end" pointcut-ref="sleep"></aop:after>
        <aop:after-returning method="ret" pointcut-ref="sleep"></aop:after-returning>
        <aop:after-throwing method="thr" pointcut-ref="sleep"></aop:after-throwing>
    </aop:aspect>
</aop:config>

*声明环绕通知

创建切面类
public class AroundAspect {
    public Object aro(ProceedingJoinPoint pjp){
        try {
            System.out.println("before");
            Object proceed = pjp.proceed();
            System.out.println("after");
            return proceed;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return null;
    }
}
声明切面的Bean
<bean id="aroundAspect" class="pray.wang.xml.aspect.AroundAspect"></bean>
声明通知
<!--环绕通知-->
<aop:config>
    <aop:pointcut id="arou" expression="execution(* pray.wang.xml..Dog.run(..))"></aop:pointcut>
    <aop:aspect ref="aroundAspect">
        <aop:around method="aro" pointcut-ref="arou"></aop:around>
    </aop:aspect>
</aop:config>

*为通知传递参数

创建切面类
public class ArgsAspect {

    public void outSpeed(Double speed){
        System.out.println("speed is "+speed);
    }
}
声明切面的Bean
<bean id="argsAspect" class="pray.wang.xml.aspect.ArgsAspect"></bean>
声明通知
<!--传递参数-->
<aop:config>
    <aop:pointcut id="sp" expression="execution(* pray.wang.xml..*.run(..)) and args(speed)"></aop:pointcut>
    <aop:aspect ref="argsAspect">
        <aop:before method="outSpeed" arg-names="speed" pointcut-ref="sp"></aop:before>
    </aop:aspect>
</aop:config>

必须保证切点参数名和通知里面的参数名一致,若通知里面的参数名不指定,则默认使用方法里面的形参的名字。

上一篇 下一篇

猜你喜欢

热点阅读