一、什么是AOP?
AOP(面向切面编程)是一种编程范式,它通过将横切关注点(如日志记录、事务管理、安全控制等)与业务逻辑分离,来提高代码的模块化程度。在SpringBoot中,AOP的实现更加简单和优雅。
二、AOP的核心概念
- 切面(Aspect):横切关注点的模块化
- 连接点(JoinPoint):程序执行过程中的某个特定位置
- 切点(Pointcut):匹配连接点的表达式
- 通知(Advice):在切点处要执行的代码
- 目标对象(Target Object):被代理的对象
三、实现步骤
1. 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2. 创建切面类
@Aspect
@Component
public class LogAspect {
private final Logger logger = LoggerFactory.getLogger(LogAspect.class);
// 定义切点
@Pointcut("execution(* com.example.demo.service.*.*(..))")
public void logPointCut() {}
// 前置通知
@Before("logPointCut()")
public void doBefore(JoinPoint joinPoint) {
logger.info("开始执行方法:" + joinPoint.getSignature().getName());
}
// 后置通知
@After("logPointCut()")
public void doAfter(JoinPoint joinPoint) {
logger.info("方法执行完成:" + joinPoint.getSignature().getName());
}
// 环绕通知
@Around("logPointCut()")
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = proceedingJoinPoint.proceed();
long endTime = System.currentTimeMillis();
logger.info("方法执行时间:" + (endTime - startTime) + "ms");
return result;
}
}
3. 使用示例
@Service
public class UserService {
public void addUser(User user) {
// 业务逻辑
System.out.println("添加用户:" + user.getName());
}
}
四、常用注解说明
- @Aspect:声明切面类
- @Pointcut:定义切点
- @Before:前置通知
- @After:后置通知
- @Around:环绕通知
- @AfterReturning:返回通知
- @AfterThrowing:异常通知
五、切点表达式
常用的切点表达式示例:
// 匹配所有public方法
@Pointcut("execution(public * *(..))")
// 匹配指定包下的所有方法
@Pointcut("execution(* com.example.demo.service.*.*(..))")
// 匹配带有特定注解的方法
@Pointcut("@annotation(com.example.demo.annotation.LogAnnotation)")
六、实际应用场景
- 日志记录:记录方法调用、参数和执行时间
- 性能监控:统计方法执行时间
- 安全控制:权限校验
- 事务管理:声明式事务
- 异常处理:统一异常处理
七、注意事项
- 切面类需要使用
@Component
注解注册为Spring组件 - 切点表达式要准确,避免影响其他方法
- 环绕通知中必须调用
proceed()
方法 - 注意切面执行顺序,可以使用
@Order
注解控制
八、总结
SpringBoot中的AOP实现非常灵活,能够有效地分离横切关注点,提高代码的可维护性和复用性。通过合理使用AOP,可以让我们的代码更加清晰、简洁。