SpringAop
注解配置方式
package com.xxxx.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* 切面
* 切入点和通知的抽象
* 定义 切入点 和 通知
* 切入点:定义要拦截哪些类的哪些方法
* 通知:定义了拦截之后方法要做什么
*/
@Component // 将对象交给IOC容器进行实例化
@Aspect // 声明当前类是一个切面
public class LogCut {
/**
* 切入点
* 定义要拦截哪些类的哪些方法
* 匹配规则,拦截什么方法
*
* 定义切入点
* @Pointcut("匹配规则")
*
* Aop切入点表达式
* 1. 执行所有的公共方法
* execution(public *(..))
* 2. 执行任意的set方法
* execution(* set*(..))
* 3. 设置指定包下的任意类的任意方法 (指定包:com.xxxx.service)
* execution(* com.xxxx.service.*.*(..))
* 4. 设置指定包及子包下的任意类的任意方法 (指定包:com.xxxx.service)
* execution(* com.xxxx.service..*.*(..))
*
* 表达式中的第一个*
* 代表的是方法的修饰范围 (public、private、protected)
* 如果取值是*,则表示所有范围
*/
@Pointcut("execution(* com.xxxx.service..*.*(..))")
public void cut(){
}
/**
* 声明前置通知,并将通知应用到指定的切入点上
* 目标类的方法执行前,执行该通知
*/
@Before(value = "cut()")
public void before() {
System.out.println("前置通知...");
}
/**
* 声明返回通知,并将通知应用到指定的切入点上
* 目标类的方法在无异常执行后,执行该通知
*/
@AfterReturning(value = "cut()")
public void afterReturn(){
System.out.println("返回通知...");
}
/**
* 声明最终通知,并将通知应用到指定的切入点上
* 目标类的方法在执行后,执行该通知 (有异常和无异常最终都会执行)
*/
@After(value = "cut()")
public void after(){
System.out.println("最终通知...");
}
/**
* 声明异常通知,并将通知应用到指定的切入点上
* 目标类的方法在执行异常时,执行该通知
*/
@AfterThrowing(value = "cut()", throwing = "e")
public void afterThrow(Exception e){
System.out.println("异常通知... ===== 异常原因:" + e.getMessage());
}
/**
* 声明环绕通知,并将通知应用到指定的切入点上
* 目标类的方法执行前后,都可通过环绕通知定义响应的处理
* 需要通过显式调用的方法,否则无法访问指定方法 pjp.proceed();
* @param pjp
* @return
*/
@Around(value = "cut()")
public Object around(ProceedingJoinPoint pjp) {
System.out.println("环绕通知-前置通知...");
Object object = null;
//object = pjp.proceed();
try{
// 显式调用对应的方法
object = pjp.proceed();
System.out.println(pjp.getTarget());
System.out.println("环绕通知-返回通知...");
} catch (Throwable throwable){
throwable.printStackTrace();
System.out.println("环绕通知-异常通知...");
}
System.out.println("环绕通知-最终通知...");
return object;
}
}
xml文件配置方式
<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
https://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">
<!-- 开启自动化扫描 -->
<context:component-scan base-package="com.xxxx"/>
<!-- aop 相关配置 -->
<aop:config>
<!-- aop 切面 -->
<aop:aspect ref="logCut02">
<!-- 定义 aop 切入点 -->
<aop:pointcut id="cut" expression="execution(* com.xxxx.service..*.*(..))"/>
<!-- 配置前置通知,设置前置通知对应的方法名及切入点 -->
<aop:before method="before" pointcut-ref="cut"/>
<!-- 配置返回通知,设置返回通知对应的方法名及切入点 -->
<aop:after-returning method="afterReturn" pointcut-ref="cut"/>
<!-- 配置最终通知,设置最终通知对应的方法名及切入点 -->
<aop:after method="after" pointcut-ref="cut"/>
<!-- 配置异常通知,设置异常通知对应的方法名及切入点 -->
<aop:after-throwing method="afterThrow" pointcut-ref="cut" throwing="e" />
<!-- 配置环绕通知,设置环绕通知对应的方法名及切入点 -->
<aop:around method="around" pointcut-ref="cut"/>
</aop:aspect>
</aop:config>
</beans>
源代码 https://github.com/Breeze1203/JavaAdvanced/tree/main/springboot-demo/spring-aop-demo