AOP通知类型
通知(Advice)定义了切面在特定连接点执行的动作,Spring AOP提供5种通知类型。
五种通知类型
前置通知 @Before
方法执行前执行,无法阻止方法执行(除非抛异常)。
Java
@Before("execution(* com.example.service.*.*(..))")
public void beforeMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println("执行方法: " + methodName);
}
后置通知 @After
方法执行后执行,无论方法成功还是抛异常都会执行。
Java
@After("execution(* com.example.service.*.*(..))")
public void afterMethod(JoinPoint joinPoint) {
System.out.println("方法执行完毕");
}
返回通知 @AfterReturning
方法成功返回后执行,可获取返回值。
Java
@AfterReturning(
pointcut = "execution(* com.example.service.*.*(..))",
returning = "result"
)
public void afterReturning(JoinPoint joinPoint, Object result) {
System.out.println("方法返回值: " + result);
}
异常通知 @AfterThrowing
方法抛出异常后执行,可获取异常信息。
Java
@AfterThrowing(
pointcut = "execution(* com.example.service.*.*(..))",
throwing = "ex"
)
public void afterThrowing(JoinPoint joinPoint, Exception ex) {
System.out.println("方法抛出异常: " + ex.getMessage());
}
环绕通知 @Around
最强大的通知,可完全控制方法执行。
Java
@Around("execution(* com.example.service.*.*(..))")
public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
// 前置逻辑
long start = System.currentTimeMillis();
// 执行目标方法
Object result = joinPoint.proceed();
// 后置逻辑
long end = System.currentTimeMillis();
System.out.println("执行耗时: " + (end - start) + "ms");
return result;
}
执行顺序
Java
正常执行流程:
@Around(前) → @Before → 目标方法 → @AfterReturning → @After → @Around(后)
异常执行流程:
@Around(前) → @Before → 目标方法(抛异常) → @AfterThrowing → @After
通知类型对比
| 通知类型 | 执行时机 | 能否获取返回值 | 能否阻止执行 | 典型应用 |
|---|---|---|---|---|
| @Before | 方法执行前 | ❌ | ❌ | 权限校验、参数验证 |
| @After | 方法执行后 | ❌ | ❌ | 资源清理 |
| @AfterReturning | 成功返回后 | ✅ | ❌ | 记录返回值 |
| @AfterThrowing | 抛异常后 | ❌(获取异常) | ❌ | 异常日志 |
| @Around | 包裹方法执行 | ✅ | ✅ | 性能监控、事务管理 |
JoinPoint常用方法
text
@Before("execution(* com.example.service.*.*(..))")
public void logMethod(JoinPoint joinPoint) {
// 方法名
String methodName = joinPoint.getSignature().getName();
// 目标类名
String className = joinPoint.getTarget().getClass().getName();
// 方法参数
Object[] args = joinPoint.getArgs();
// 方法签名
Signature signature = joinPoint.getSignature();
}
要点总结
- 5种通知:前置、后置、返回、异常、环绕
- @Before/@After无法获取返回值,@AfterReturning可以
- @Around最强大,可控制方法是否执行
- 执行顺序:Around前→Before→目标方法→返回/异常→After→Around后
- 环绕通知必须调用proceed()才会执行目标方法
📝 发现内容有误?点击此处直接编辑