-
导入坐标依赖
<dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <!--Spring Aspects--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!--aspectj--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.3</version> </dependency>
<?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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> </beans>
-
编写spirng配置文件中AOP的配置部分
<!-- bean管理--> <bean id="us" class="com.qc.service.impl.UserServiceImpl"/> <bean id="myAspect" class="com.qc.util.MyAspect"/> <!-- 配置aop--> <aop:config> <!-- 配置切面--> <aop:aspect ref="myAspect"> <!-- 前缀通知--> <aop:before method="log1" pointcut="execution(public void com.qc.service.impl.UserServiceImpl.save())"/> <!-- 后置通知--> <aop:after-returning method="log2" pointcut="execution(public void com.qc.service.impl.UserServiceImpl.save())"/> <!-- 异常通知--> <aop:after-throwing method="log3" pointcut="execution(public void com.qc.service.impl.UserServiceImpl.save())"/> <!-- 最终通知--> <aop:after method="log4" pointcut="execution(public void com.qc.service.impl.UserServiceImpl.save())"/> <!-- 环绕通知--> <aop:around method="aroundLog" pointcut="execution(public void com.qc.service.impl.UserServiceImpl.save())"/> </aop:aspect> </aop:config>
import org.aspectj.lang.ProceedingJoinPoint; public class MyAspect { // 自定义切面类 = 切入点+通知 //通知 public void log1() { System.out.println("前置增强的"); } public void log2() { System.out.println("后置增强的"); } public void log3() { System.out.println("异常增强的"); } public void log4() { System.out.println("最终增强的"); } public void aroundLog(ProceedingJoinPoint point) { try { log1(); point.proceed(); // 目标方法调用 log2(); } catch (Throwable e) { e.printStackTrace(); log3(); } finally { log4(); } } }
注意环绕通知使用的接口
通知类型
- 前置通知:目标方法执行前进行增强
- 后置通知:目标方法执行后进行增强
- 异常通知:目标方法出现异常后进行增强
- 最终通知:目标方法无论是否异常都进行增强
- 环绕通知:目标方法执行前后,都进行增强,不过需要自己书写
切入点表达式
- execution([修饰符] 返回值 包名.类名.方法名(参数))
- 修饰符可以省略不写
- 返回值类型不能省略,根据方法来编写返回值,可以用星号来代替
- 包名类型方法名是不能省略的,但是可以用星号来代替,也可以部分代替
- 参数如果是一个可以用星号来代替,如果是多个可以使用两个点
因此比较通用的表达式:
execution( com.qc.*.Service.save(…))