题目
Spring AOP中常用的通知类型有哪些?请简述其执行时机
信息
- 类型:问答
- 难度:⭐
考点
Spring AOP基础,通知类型,执行时机
快速回答
Spring AOP包含5种核心通知类型:
- Before Advice:目标方法执行前触发
- After Returning Advice:目标方法成功返回后触发
- After Throwing Advice:目标方法抛出异常后触发
- After (Finally) Advice:目标方法结束后触发(无论成功或异常)
- Around Advice:包裹目标方法,可控制方法执行
1. 通知类型详解与执行时机
- @Before:
适用于权限校验、日志记录等@Before("execution(* com.example.service.*.*(..))") public void logBefore(JoinPoint jp) { // 记录方法调用日志 } - @AfterReturning:
适用于成功操作后的日志、结果处理@AfterReturning(pointcut = "...", returning = "result") public void logReturn(Object result) { // 处理返回值 } - @AfterThrowing:
适用于统一异常处理@AfterThrowing(pointcut = "...", throwing = "ex") public void handleException(JoinPoint jp, Exception ex) { // 异常处理逻辑 } - @After:
适用于资源清理等必须执行的操作@After("execution(* com.example.service.*.*(..))") public void releaseResource() { // 资源释放(如关闭文件) } - @Around:
适用于性能监控、事务管理等@Around("execution(* com.example.service.*.*(..))") public Object measureTime(ProceedingJoinPoint pjp) throws Throwable { long start = System.currentTimeMillis(); Object result = pjp.proceed(); // 控制目标方法执行 long duration = System.currentTimeMillis() - start; return result; }
2. 核心原理
Spring AOP通过动态代理实现:
- JDK动态代理:基于接口(需实现接口)
- CGLIB代理:基于类继承(无接口时使用)
代理对象在方法调用时插入通知逻辑,形成调用链:
Around前 → Before → 目标方法 → Around后 → AfterReturning/AfterThrowing → After
3. 最佳实践
- 优先使用声明式注解(如@Aspect)而非XML配置
- Around中必须调用
proceed()否则会阻断目标方法 - 避免在通知中修改输入参数(破坏封装性)
4. 常见错误
- 混淆After和AfterReturning:After始终执行,AfterReturning仅在成功返回时执行
- Around通知忘记调用
proceed()导致业务方法未执行 - 在同一个切面内,通知执行顺序由@Order注解控制,未指定时顺序不确定
5. 扩展知识
- JoinPoint对象:可获取方法签名、参数等信息
- ProceedingJoinPoint:专用于Around通知,提供
proceed()方法 - 使用@Pointcut定义可重用的切点表达式