Spring-AOP-实现原理
Spring-AOP-实现原理
AOP 本质回顾
AOP(Aspect Oriented Programming)面向切面编程:
在不修改原始业务代码的情况下,对方法调用前后进行增强。
常见例子:
1 |
|
当我们调用:
1 | userService.saveUser(); |
Spring 实际调用的不是 UserServiceImpl,而是一个 代理对象(Proxy)。
代理对象创建过程
入口方法在 AnnotationAwareAspectJAutoProxyCreator
这是一个特殊的 BeanPostProcessor,会在 Bean 初始化阶段判断是否需要创建代理。
📌 调用链:
- 容器创建 Bean → 调用 BeanPostProcessor
AnnotationAwareAspectJAutoProxyCreator
检查 Bean 是否匹配切面- 如果匹配 → 调用
ProxyFactory
创建代理对象 - 用
JdkDynamicAopProxy
或CglibAopProxy
生成代理
判断使用哪种代理方式
在 DefaultAopProxyFactory#createAopProxy
:
1 | public AopProxy createAopProxy(AdvisedSupport config) { |
- 如果 Bean 实现了接口 → 使用 JDK 动态代理
- 如果 Bean 没有接口 → 使用 CGLIB 代理
JDK 动态代理核心
以 JDK 代理为例(JdkDynamicAopProxy
):
1 |
|
👉 这段代码就是 Spring AOP 的灵魂:
- 拿到该方法对应的所有 拦截器(Advice)
- 如果没有增强,直接执行目标方法
- 如果有增强,就构造一个 MethodInvocation 调用链,按顺序调用每个拦截器
拦截器链(Interceptor Chain)
Spring 把每个切面包装成一个 MethodInterceptor
。
例如:
1 |
|
最终会被封装成:
1 | MethodBeforeAdviceInterceptor |
而执行过程在:
1 | ReflectiveMethodInvocation#proceed() |
1 | public Object proceed() throws Throwable { |
📌 这就是一个典型的责任链模式。
每个拦截器调用 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: 返回最终结果
调试建议
- 在
AnnotationAwareAspectJAutoProxyCreator#postProcessAfterInitialization
打断点- 看哪些 Bean 被代理了
- 跟进
ProxyFactory
→JdkDynamicAopProxy
- 看
getProxy()
是如何生成代理类
- 看
- 在
JdkDynamicAopProxy#invoke
打断点- 看拦截器链是如何执行的
打印拦截器链内容:1
System.out.println(advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass));
- 看拦截器链是如何执行的
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.