Spring-AOP-实现原理

AOP 本质回顾

AOP(Aspect Oriented Programming)面向切面编程:
在不修改原始业务代码的情况下,对方法调用前后进行增强。
常见例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Aspect
@Component
public class LogAspect {
@Before("execution(* com.example.service.*.*(..))")
public void before() {
System.out.println("方法执行前");
}

@After("execution(* com.example.service.*.*(..))")
public void after() {
System.out.println("方法执行后");
}
}

当我们调用:

1
userService.saveUser();

Spring 实际调用的不是 UserServiceImpl,而是一个 代理对象(Proxy)

代理对象创建过程

入口方法在 AnnotationAwareAspectJAutoProxyCreator
这是一个特殊的 BeanPostProcessor,会在 Bean 初始化阶段判断是否需要创建代理。

📌 调用链:

  1. 容器创建 Bean → 调用 BeanPostProcessor
  2. AnnotationAwareAspectJAutoProxyCreator 检查 Bean 是否匹配切面
  3. 如果匹配 → 调用 ProxyFactory 创建代理对象
  4. JdkDynamicAopProxyCglibAopProxy 生成代理

判断使用哪种代理方式
DefaultAopProxyFactory#createAopProxy

1
2
3
4
5
6
7
public AopProxy createAopProxy(AdvisedSupport config) {
if (config.isProxyTargetClass() || hasNoInterfaces(config)) {
return new CglibAopProxy(config);
} else {
return new JdkDynamicAopProxy(config);
}
}
  • 如果 Bean 实现了接口 → 使用 JDK 动态代理
  • 如果 Bean 没有接口 → 使用 CGLIB 代理

JDK 动态代理核心

以 JDK 代理为例(JdkDynamicAopProxy):

1
2
3
4
5
6
7
8
9
10
11
12
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

if (chain.isEmpty()) {
return method.invoke(target, args);
} else {
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, chain);
return invocation.proceed();
}
}

👉 这段代码就是 Spring AOP 的灵魂:

  • 拿到该方法对应的所有 拦截器(Advice)
  • 如果没有增强,直接执行目标方法
  • 如果有增强,就构造一个 MethodInvocation 调用链,按顺序调用每个拦截器

拦截器链(Interceptor Chain)

Spring 把每个切面包装成一个 MethodInterceptor
例如:

1
2
@Before
public void before() {}

最终会被封装成:

1
MethodBeforeAdviceInterceptor

而执行过程在:

1
ReflectiveMethodInvocation#proceed()
1
2
3
4
5
6
7
8
9
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
// 调用目标方法
return method.invoke(target, arguments);
}

Object interceptor = this.interceptorsAndDynamicMethodMatchers.get(++currentInterceptorIndex);
return ((MethodInterceptor) interceptor).invoke(this);
}

📌 这就是一个典型的责任链模式。
每个拦截器调用 invocation.proceed() 时,进入下一个拦截器。

调用链时序图

sequenceDiagram
    participant Client
    participant Proxy
    participant AOPInterceptor1
    participant AOPInterceptor2
    participant Target

    Client->>Proxy: 调用 saveUser()
    Proxy->>AOPInterceptor1: invoke()
    AOPInterceptor1->>AOPInterceptor2: invocation.proceed()
    AOPInterceptor2->>Target: method.invoke()
    Target-->>AOPInterceptor2: 返回结果
    AOPInterceptor2-->>AOPInterceptor1: 返回结果
    AOPInterceptor1-->>Client: 返回最终结果

调试建议

  1. AnnotationAwareAspectJAutoProxyCreator#postProcessAfterInitialization 打断点
    • 看哪些 Bean 被代理了
  2. 跟进 ProxyFactoryJdkDynamicAopProxy
    • getProxy() 是如何生成代理类
  3. JdkDynamicAopProxy#invoke 打断点
    • 看拦截器链是如何执行的
      打印拦截器链内容:
      1
      System.out.println(advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass));