三、XML配置实现AOP
将LogAspect和AerifiyAspect类上及方法上的注解全部注释。
基于注解的AOP实现步骤:
- 将目标类和切面类上添加@Component,交个Spring容器管理
- 切面类添加@Aspect,表明这是一个切面类
- 切面类方法中添加通知方法的注解
- xml配置中开启AOP功能,并使用component-scan扫描所有包
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <context:component-scan base-package="com.citi"> </context:component-scan> <!--xml AOP配置--> <!--配置目标类和切面类, @Component--> <bean id="logAspect" class="com.citi.aspect.LogAspect"></bean> <bean id="aerifyAspect" class="com.citi.aspect.AerifyAspect"></bean> <bean id="appleCalculator" class="com.citi.util.impl.AppleCalculator"></bean> <!--AOP配置,通知方法配置--> <aop:config> <!--指定切面,@Aspect, ref属性引用容器中已存在的Bean,order属性决定运行先后次序顺序--> <aop:aspect ref="logAspect" order="1"> <!--配置切点表达式@Pointcut--> <aop:pointcut id="addPointcut" expression="execution(public * com.citi.util.impl.AppleCalculator.add(int, int))"></aop:pointcut> <aop:pointcut id="divPointcut" expression="execution(public * com.citi.util.impl.AppleCalculator.div(int, int))"></aop:pointcut> <!--配置通知方法@Before,@After...--> <!--logStart方法中有参数jointPoint,它是Spring知道的变量,不用配置在xml属性中--> <aop:before method="logStart" pointcut-ref="addPointcut"></aop:before> <!--logReturn方法中有参数 Object result,Spring不知道这个变量,xml中使用returning属性来接收--> <aop:after-returning method="logReturn" returning="result" pointcut-ref="addPointcut"></aop:after-returning> <aop:after-throwing method="logStart" pointcut-ref="addPointcut"></aop:after-throwing> <aop:after method="logStart" pointcut-ref="addPointcut"></aop:after> </aop:aspect> <aop:aspect ref="aerifyAspect" order="3"> <!--配置切点表达式@Pointcut--> <aop:pointcut id="addPointcut" expression="execution(public * com.citi.util.impl.AppleCalculator.add(int, int))"></aop:pointcut> <!--配置通知方法@Before,@After...--> <!--logStart方法中有参数jointPoint,它是Spring知道的变量,不用配置在xml属性中--> <aop:before method="verifyStart" pointcut-ref="addPointcut"></aop:before> <!--logReturn方法中有参数 Object result,Spring不知道这个变量,xml中使用returning属性来接收--> <aop:after-returning method="verifyReturn" returning="result" pointcut-ref="addPointcut"></aop:after-returning> <aop:after-throwing method="verifyException" throwing="e" pointcut-ref="addPointcut"></aop:after-throwing> <aop:after method="verifyEnd" pointcut-ref="addPointcut"></aop:after> </aop:aspect> </aop:config> <!--开启AOP--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans> 复制代码
环绕前置通知的顺序和普通普通前置通知的顺序于xml配置先后顺序有关,如果先配置<aop:around>就先打印环绕通知,如果<aop:before>在前就先打印普通前置通知
执行测试
至此,Spring AOP 告一段落🎉