什么是AOP?
AOP(Aspect Oriented Programming)即面向切面编程,是一种编程范式,允许开发者将横切关注点(如日志、事务、性能监控)从核心业务逻辑中分离,实现代码的高效复用和解耦。
典型应用场景
- 性能监控:统计方法执行耗时
- 日志记录:统一记录接口调用信息
- 事务管理:自动开启/提交事务
- 权限校验:拦截未授权请求
AOP的四大优势
- 减少重复代码:将通用逻辑集中处理
- 无侵入性:不修改原始业务代码
- 提升开发效率:聚焦核心功能开发
- 易于维护:功能变更只需修改切面
AOP核心概念解析
概念 | 说明 |
---|---|
连接点 | 程序执行中的特定点(如方法调用),包含执行上下文信息 |
通知 | 封装横切逻辑的方法(如记录耗时) |
切入点 | 定义哪些连接点会触发通知(通过表达式匹配) |
切面 | 通知 + 切入点的结合体,描述"何时何地做什么" |
目标对象 | 被代理的原始对象(如Service实例) |
AOP通知类型详解
五类通知的执行时机
@Around
- 包裹目标方法,手动控制方法执行
- 必须返回
Object
,接收原始方法返回值
java@Around("pt()") public Object around(ProceedingJoinPoint pjp) throws Throwable { // 前置逻辑 Object result = pjp.proceed(); // 后置逻辑 return result; }
@Before
- 目标方法执行前触发
@After
- 目标方法执行后触发(无论是否异常)
@AfterReturning
- 目标方法正常返回后触发
@AfterThrowing
- 目标方法抛出异常后触发
高效使用@PointCut
通过抽取公共切入点表达式,提升代码复用性:
java
// 定义公共切入点
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceMethods() {}
// 多个通知复用同一个切入点
@Before("serviceMethods()")
public void logStart(JoinPoint jp) {
// 记录方法开始
}
@AfterReturning("serviceMethods()")
public void logSuccess(JoinPoint jp) {
// 记录成功执行
}
可见性规则:
private
:仅当前切面类可用public
:支持跨切面类复用
多切面执行顺序控制
默认行为
按切面类名排序:
- 前置通知:字母序靠前的先执行(如
AService
早于BService
) - 后置通知:字母序靠前的后执行(类似栈结构)
自定义顺序
使用@Order(数字)
注解:
- 数字越小优先级越高
- 前置通知:数值小的先执行
- 后置通知:数值小的先执行
java
@Aspect
@Order(1) // 最高优先级
public class LogAspect {
// ...
}
总结与最佳实践
选择通知类型:
- 需要控制方法执行 →
@Around
- 简单前置/后置处理 → 其他四类
- 需要控制方法执行 →
优先使用公共切入点:
- 通过
@PointCut
提升代码可维护性
- 通过
明确切面顺序:
- 默认按类名排序,重要切面使用
@Order
显式声明
- 默认按类名排序,重要切面使用
通过合理运用AOP,开发者能构建出高内聚,低耦合的优雅系统架构。建议从简单的日志、耗时系统入手,逐步探索事务管理、权限控制等高级用法。