在基于Spring框架的开发中,你是否思考过:为何一个简单的 @Aspect 注解就能让方法拥有拦截能力?其背后的动态代理机制是如何运作的?本文将深入 CglibAopProxy 的源码,从代理对象的生成到方法拦截的完整链路,逐层剖析,帮助你彻底理解 Spring AOP 的核心实现原理。
一、CglibAopProxy 的核心角色:代理对象的创建入口
Spring AOP 的代理机制主要有两种实现:基于接口的 JDK 动态代理和基于继承的 CGLIB 代理。当目标类未实现任何接口时,Spring 默认会选用 CglibAopProxy。整个过程的起点是 ProxyFactory 的 getProxy() 方法,它是获取代理对象的统一入口。
// ProxyFactory.java
public Object getProxy() {
return createAopProxy().getProxy();
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// 根据目标类是否有接口,选择 JDK 或 CGLIB 代理
return getAopProxyFactory().createAopProxy(this);
}
当判定目标类没有接口时,createAopProxy() 方法会返回一个 CglibAopProxy 实例。接下来,我们聚焦于 CglibAopProxy.getProxy() 方法,这是生成 CGLIB 代理对象的核心。
二、CGLIB 代理对象的生成:基于 Enhancer 创建动态子类
CGLIB 通过 Enhancer 类为目标类创建动态子类(即代理类)。以下是 CglibAopProxy.getProxy() 方法的核心逻辑:
// CglibAopProxy.java
public Object getProxy() {
try {
Class<?> targetClass = getTargetClass();
Enhancer enhancer = createEnhancer();
// 1. 设置父类(即目标类)
enhancer.setSuperclass(targetClass);
// 2. 设置类加载器
enhancer.setClassLoader(getProxyClassLoader());
// 3. 设置回调(核心拦截器)
enhancer.setCallbacks(new Callback[] {
dynamicAdvisedInterceptor,
new FixedValue() {
public Object loadObject() {
return null;
}
}
});
// 4. 设置回调过滤器(决定使用哪个 Callback)
enhancer.setCallbackFilter(new CallbackFilter() {
public int accept(Method method) {
return 0;
}
});
// 5. 生成代理实例
return enhancer.create();
} catch (Exception e) {
throw new AopConfigException("Could not generate CGLIB proxy", e);
}
}
此处的 dynamicAdvisedInterceptor 是 DynamicAdvisedInterceptor 类型的一个实例,它作为 CGLIB 代理的核心拦截器,所有对代理对象的方法调用最终都会路由到它的 intercept() 方法。
三、方法拦截的核心:DynamicAdvisedInterceptor.intercept()
当调用代理对象的方法时,CGLIB 会触发 DynamicAdvisedInterceptor.intercept() 方法。我们来看这个方法的关键步骤:
// DynamicAdvisedInterceptor.java
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object target = getTarget();
try {
// 1. 获取适用于当前方法的增强链(Advisor 列表)
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// 2. 如果增强链为空且方法是 public 的,直接调用目标方法
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
retVal = methodProxy.invoke(target, args);
} else {
// 3. 创建方法调用器,并执行增强链
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
return retVal;
} finally {
releaseTarget(target);
}
}
这里的 chain 包含了为该方法配置的所有增强器(例如 @Before、@After 等 Advice 对应的拦截器)。CglibMethodInvocation.proceed() 方法负责按既定顺序执行这条增强链,这种链式调用是系统设计中责任链模式的典型应用。
四、增强链的执行:MethodInvocation.proceed() 的递归调用
CglibMethodInvocation 继承自 ReflectiveMethodInvocation,其 proceed() 方法是执行增强链的核心:
// ReflectiveMethodInvocation.java
public Object proceed() throws Throwable {
// 1. 如果所有增强都已执行完毕,则调用原始目标方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 2. 获取下一个要执行的增强器
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 3. 执行增强器逻辑
if (interceptorOrInterceptionAdvice instanceof MethodInterceptor) {
MethodInterceptor mi = (MethodInterceptor) interceptorOrInterceptionAdvice;
return mi.invoke(this);
} else {
// 处理动态匹配的增强器
return ((DynamicMethodMatcherPointcutAdvisor) interceptorOrInterceptionAdvice)
.getInterceptionAdvice().invoke(this);
}
}
这个方法采用了一种巧妙的递归式调用:每个 MethodInterceptor 在执行完自身逻辑后,会再次调用 proceed(),从而驱动链条向下一个拦截器推进,直到所有增强执行完毕,最终调用原始目标方法(invokeJoinpoint())。
五、核心流程 UML 时序图
为了更直观地展示从代理创建到方法拦截的完整流程,以下 UML 时序图清晰地描述了各组件间的交互:

六、总结:CglibAopProxy 的底层逻辑剖析
Spring CglibAopProxy 的实现逻辑可以清晰地归纳为三个核心步骤:
- 生成代理对象:利用 CGLIB 的
Enhancer 为目标类创建动态子类,并将 DynamicAdvisedInterceptor 设置为统一的回调拦截器。
- 方法拦截:代理对象上的任何方法调用都会被
DynamicAdvisedInterceptor.intercept() 捕获,并获取对应的增强器链。
- 链式执行:通过
MethodInvocation.proceed() 方法递归执行增强链中的每个拦截器,最终调用原始目标方法完成业务逻辑。
本质上,Spring AOP 的魔法并不复杂,其核心是在运行时通过动态代理技术生成新类,并将横切关注点(增强逻辑)以链式调用的方式“编织”到原有方法调用流程中。深入理解 CglibAopProxy 的源码,是掌握 Spring AOP架构原理和进行高效问题排查的关键。