AOP 概念:切点/通知/织入与通知顺序

结论先行:AOP(面向切面编程)把日志、事务、权限、监控这类"横切关注点"从业务代码中抽出来独立成切面。五个核心概念:切面(Aspect)、连接点(JoinPoint)、切点(Pointcut)、通知(Advice)、织入(Weaving)。一句话定位:切点决定"切哪里",通知决定"做什么",织入决定"什么时候生效"(Spring 采用运行期动态代理织入)。多个切面的执行顺序由 @Order 决定,@Order 数值小者先执行、包裹在外层。

一、概念速查

术语含义类比/要点
Aspect 切面切点 + 通知的封装(@Aspect 类)一个模块化的横切逻辑
JoinPoint 连接点被拦截的可执行位置Spring AOP 中仅指"方法执行"
Pointcut 切点匹配连接点的表达式execution()/within/@annotation(...) 等
Advice 通知切点处要执行的动作五种:@Before/@After/@AfterReturning/@AfterThrowing/@Around
Weaving 织入把通知应用到目标生成代理的过程Spring = 运行期动态代理织入

二、代码示例

@Aspect
@Component
public class LogAspect {
    @Pointcut("execution(* com.demo.service.*.*(..))")   // 切点:service 包下所有方法
    public void serviceLayer() { }

    @Around("serviceLayer()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis();
        try {
            return pjp.proceed();                        // 放行目标方法
        } finally {
            System.out.println(pjp.getSignature() + " cost " + (System.currentTimeMillis() - start) + "ms");
        }
    }
}

三、通知执行顺序(Spring 5.2.7+)

  • 正常返回:@Around 前段 → @Before → 目标方法 → @AfterReturning → @After → @Around 后段;
  • 抛异常:@Around 前段 → @Before → 目标方法抛异常 → @AfterThrowing → @After → @Around 后段(finally 部分仍执行);
  • 多切面嵌套:@Order(1) 在最外层,@Order 越大越内层;@Around 不调用 proceed() 则目标方法不执行。

常见追问 / 记忆点

  • 追问 1:五种通知怎么选?答:读操作善用 @Before/@AfterReturning;需要吞异常、控制返回值或统计耗时用 @Around(最灵活、可决定是否放行)。
  • 追问 2:execution 表达式写法?答:execution(修饰符 返回类型 类路径.方法(参数) 异常),如 execution(* com.demo.service..(..))。
  • 追问 3:为什么通知顺序重要?答:事务/缓存/安全等切面叠加时顺序错了会先提交后收尾,导致逻辑错乱;用 @Order 显式控制。
  • 记忆点:"切点定位置、通知定动作、织入定时机、@Order 定先后"。
笔记加载中…