在Java的SpringAOP中,切面类的注解模式主要分为5种通知类型,其中@Around是最灵活的环绕型通知。除了@Around,其他四种常用的通知类型如下:
1. 前置通知(@Before)
- 作用:在目标方法执行之前触发。
- 特点:如果在@Before中抛出异常,目标方法不会执行,直接进入异常流程。常用于权限校验、日志记录、参数预处理等场景。
示例:
@Aspect
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("方法开始执行: " + joinPoint.getSignature().getName());
}
}
2. 后置通知(@After)
- 作用:在目标方法执行完毕之后触发(无论是否抛出异常)。
- 特点:即使方法抛出异常,@After仍会执行。常用于资源释放、清理操作等场景。
示例:
@Aspect
public class ResourceAspect {
@After("execution(* com.example.service.*.*(..))")
public void releaseResource() {
System.out.println("方法执行完成,释放资源");
}
}
3. 返回后通知 (@AfterReturning)
- 作用:在目标方法成功返回后触发(仅当方法正常结束且未抛出异常时执行)。
- 特点:可以获取方法的返回值。适用于处理返回值、缓存结果等场景。
示例:
@Aspect
public class CacheAspect {
@AfterReturning(pointcut = "execution(* com.example.service.UserService.getUserById(..))",
returning = "user")
public void cacheUser(User user) {
System.out.println("缓存用户信息: " + user.getId());
}
}
4. 异常后通知(@AfterThrowing)
- 作用:在目标方法抛出异常后触发。
- 特点:需要指定异常类型,可精准捕获特定异常。适用于全局异常处理、错误日志记录等场景。
示例:
@Aspect
public class ExceptionAspect {
@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))",
throwing = "ex")
public void handleException(Throwable ex) {
System.out.println("捕获到异常: " + ex.getMessage());
}
}
5. 环绕通知(@Around)
- 作用:通过ProceedingJoinPoint完全控制目标方法的执行流程(前、中、后)。
- 特点:最灵活的通知类型,可替代其他四种通知。需手动调用 proceed() 才能继续执行目标方法。常用于事务管理、动态代理等场景。
示例:
@Aspect
public class TransactionAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object manageTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("开始事务");
try {
Object result = joinPoint.proceed(); // 执行目标方法
System.out.println("提交事务");
return result;
} catch (Exception e) {
System.out.println("回滚事务");
throw e;
}
}
}
选择建议
- 简单前置/后置逻辑→优先用 @Before/@After 。
- 需处理返回值 → 用@AfterReturning 。
- 需处理特定异常→用@AfterThrowing 。
- 需精细控制流程(如事务→用@Around 。