3. Spring AOP编程
大约 3 分钟
3. Spring AOP编程
概述
面向切面编程(AOP)是Spring框架的另一个核心概念,它允许将横切关注点(如日志、事务)从业务逻辑中分离出来。AOP的核心思想是将应用程序中的关注点分离,使得代码更加清晰、可维护。
知识要点
1. AOP的核心概念
- 切面(Aspect): 横切关注点的模块化,它包含了通知和切点。
- 连接点(Joinpoint): 程序执行过程中的一个点,如方法的执行、异常的抛出等。
- 通知(Advice): 切面在特定连接点上执行的动作,包括前置通知、后置通知、环绕通知、异常通知和最终通知。
- 切点(Pointcut): 定义了哪些连接点会被拦截,通常使用表达式来定义。
- 引入(Introduction): 允许向现有的类添加新的方法或字段。
2. 通知的类型
- 前置通知(Before): 在连接点执行之前执行的通知。
- 后置通知(After): 在连接点执行之后执行的通知,无论连接点是否正常执行。
- 返回通知(After-returning): 在连接点正常执行之后执行的通知。
- 异常通知(After-throwing): 在连接点抛出异常之后执行的通知。
- 环绕通知(Around): 包围连接点的通知,它可以在连接点执行之前和之后执行,甚至可以控制是否执行连接点。
3. 代码示例
切面类的定义
@Aspect
@Component
public class LoggingAspect {
// 前置通知
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}
// 后置通知
@After("execution(* com.example.service.*.*(..))")
public void logAfter(JoinPoint joinPoint) {
System.out.println("After method: " + joinPoint.getSignature().getName());
}
// 环绕通知
@Around("execution(* com.example.service.*.*(..))")
public Object logAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("Around method start: " + proceedingJoinPoint.getSignature().getName());
Object result = proceedingJoinPoint.proceed();
System.out.println("Around method end: " + proceedingJoinPoint.getSignature().getName());
return result;
}
}
启用AOP
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
// 配置其他bean
}
4. 切点表达式
- execution: 用于匹配方法执行的连接点。
- within: 用于匹配特定类型内的所有方法。
- this: 用于匹配特定类型的bean的方法。
- target: 用于匹配特定目标类型的方法。
- args: 用于匹配特定参数类型的方法。
- @annotation: 用于匹配带有特定注解的方法。
知识扩展
设计思想
AOP的设计思想是关注点分离,它通过将横切关注点(如日志、事务)从业务逻辑中分离出来,使得代码更加清晰、可维护。
避坑指南
- 避免过度使用AOP,否则会导致代码难以理解和调试。
- 注意切点表达式的精度,避免拦截不必要的方法。
- 注意通知的执行顺序,特别是当有多个切面时。
深度思考题
深度思考题: 环绕通知和其他通知有什么区别? 思考题回答: 环绕通知包围连接点,它可以在连接点执行之前和之后执行,甚至可以控制是否执行连接点;而其他通知只在连接点的特定时刻执行,不能控制连接点的执行。
深度思考题: 什么是AspectJ?它和Spring AOP有什么区别? 思考题回答: AspectJ是一个完整的AOP框架,它提供了更强大的AOP功能,包括编译时织入、加载时织入等;而Spring AOP是基于代理的AOP实现,它只支持运行时织入,而且只支持方法级别的连接点。不过,Spring AOP可以集成AspectJ,以获得更强大的AOP功能。