Spring 动态代理是 Spring AOP 的核心实现机制,主要分为 JDK 动态代理(基于接口)和 CGLIB 动态代理(基于类)两种方式。下面从源码层面,由浅入深拆解其核心实现逻辑。
一、核心入口:AopProxy 接口
Spring 抽象了动态代理的统一入口,所有代理实现都遵循 AopProxy 接口,核心方法是 getProxy()(获取代理对象)。
public interface AopProxy {
// 获取代理对象(使用默认类加载器)
Object getProxy();
// 指定类加载器获取代理对象
Object getProxy(@Nullable ClassLoader classLoader);
}
Spring 为该接口提供了两个核心实现:
JdkDynamicAopProxy:JDK 动态代理实现(必须实现接口)CglibAopProxy:CGLIB 动态代理实现(可代理无接口的类)
二、代理对象创建的核心流程
Spring 不会直接创建 AopProxy,而是通过 DefaultAopProxyFactory 选择代理类型并创建实例,核心逻辑如下:
1. 代理类型选择:DefaultAopProxyFactory
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 判断条件:是否优化 | 是否有接口 | 是否强制使用CGLIB
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("Target class must be specified for proxy creation");
}
// 如果目标类是接口/是JDK代理类,仍用JDK代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 否则使用CGLIB代理
return new ObjenesisCglibAopProxy(config);
} else {
// 有接口且未强制CGLIB,使用JDK代理
return new JdkDynamicAopProxy(config);
}
}
// 判断是否没有用户提供的代理接口(仅存在Spring的ProxyConfig接口不算)
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class<?>[] interfaces = config.getProxiedInterfaces();
return interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class.isAssignableFrom(interfaces[0]));
}
}
核心判断逻辑:
- 如果设置了
proxyTargetClass=true(强制代理类)、目标类无接口,优先用 CGLIB; - 如果目标类是接口 / 已是 JDK 代理类,用 JDK 代理;
- 其他情况默认用 JDK 代理。
三、JDK 动态代理源码解析(JdkDynamicAopProxy)
1. 核心实现:invoke 方法
JDK 动态代理基于 java.lang.reflect.Proxy 和 InvocationHandler,JdkDynamicAopProxy 实现了 InvocationHandler,核心逻辑在 invoke 方法:
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
private final AdvisedSupport advised;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
// 目标对象
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
// 1. 处理equals/hashCode等Object方法(如果未被切面增强)
if (!this.advised.opaque && method.getDeclaringClass() == Object.class && method.getName().equals("equals")) {
return equals(args[0]);
} else if (!this.advised.opaque && method.getDeclaringClass() == Object.class && method.getName().equals("hashCode")) {
return hashCode();
}
// 2. 检查是否需要暴露代理对象到ThreadLocal(用于嵌套调用)
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 3. 获取目标对象(从TargetSource中,支持原型/单例等)
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 4. 获取当前方法的拦截器链(Advice -> Interceptor)
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// 5. 如果没有拦截器链,直接调用目标方法
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
} else {
// 6. 有拦截器链,创建MethodInvocation并执行拦截器链
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
// 7. 处理返回值(适配基本类型、包装类型等)
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
} else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
} finally {
// 8. 释放目标对象(TargetSource的release方法)
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
// 9. 恢复ThreadLocal中的代理对象
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
// 获取代理对象(JDK Proxy核心方法)
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// JDK核心API:Proxy.newProxyInstance创建代理对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
}
2. 拦截器链执行:ReflectiveMethodInvocation
拦截器链的执行核心在 ReflectiveMethodInvocation 的 proceed() 方法(责任链模式):
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
private final List<Object> interceptorsAndDynamicMethodMatchers;
private int currentInterceptorIndex = -1;
@Override
public Object proceed() throws Throwable {
// 1. 如果所有拦截器都执行完,调用目标方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 2. 获取下一个拦截器
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// 动态匹配(方法匹配器)
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
} else {
// 不匹配则跳过当前拦截器,继续执行下一个
return proceed();
}
} else {
// 3. 执行拦截器(如BeforeAdvice、AroundAdvice等)
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
// 调用目标方法(最终的joinpoint)
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
}
四、CGLIB 动态代理源码解析(CglibAopProxy)
1. 核心实现:Enhancer 与 MethodInterceptor
CGLIB(Code Generation Library)通过动态生成目标类的子类实现代理,Spring 封装了 CglibAopProxy,核心依赖 net.sf.cglib.proxy.Enhancer 和 MethodInterceptor。
(1)创建代理对象:getProxy 方法
public class CglibAopProxy implements AopProxy, Serializable {
private final AdvisedSupport advised;
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for CGLIB proxy creation");
Class<?> proxySuperClass = rootClass;
// 处理CGLIB生成的子类(避免重复代理)
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// 1. 验证目标类(不能是final,否则无法生成子类)
validateClassIfNecessary(proxySuperClass, classLoader);
// 2. 创建CGLIB Enhancer(核心类,用于生成子类)
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader && ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
// 3. 设置Enhancer参数(父类、回调、接口等)
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
// 4. 设置回调(核心:DynamicAdvisedInterceptor)
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
enhancer.setCallbacks(callbacks);
// 5. 生成并返回代理子类实例
return createProxyClassAndInstance(enhancer);
} catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass(), ex);
}
}
}
(2)核心回调:DynamicAdvisedInterceptor
CGLIB 的拦截逻辑在 DynamicAdvisedInterceptor(实现了 MethodInterceptor),类似 JDK 代理的 invoke 方法:
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.targetSource;
try {
// 1. 暴露代理对象到ThreadLocal(同JDK代理)
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 2. 获取目标对象
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 3. 获取拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// 4. 无拦截器链,直接调用目标方法(CGLIB的methodProxy.invokeSuper)
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
retVal = methodProxy.invokeSuper(proxy, args);
} else {
// 5. 有拦截器链,创建CglibMethodInvocation执行
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
// 6. 处理返回值(同JDK代理)
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
} finally {
// 7. 释放目标对象、恢复ThreadLocal
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
五、关键对比:JDK vs CGLIB 代理
| 维度 | JDK 动态代理 | CGLIB 动态代理 |
|---|---|---|
| 底层原理 | 基于接口 + InvocationHandler | 基于继承(生成子类)+ MethodInterceptor |
| 代理条件 | 目标类必须实现接口 | 目标类不能是 final,方法不能是 final |
| 性能 | JDK8+ 性能优于 CGLIB(调用快) | 生成代理类时稍慢,调用略慢 |
| 核心 API | Proxy.newProxyInstance() | Enhancer.create() |
六、源码核心关键点
- AdvisedSupport:封装了代理的核心配置(目标对象、拦截器、代理类型等),是连接目标对象和代理的桥梁;
- 拦截器链 :Spring 将
Advice(通知)转换为MethodInterceptor,通过责任链模式执行(ReflectiveMethodInvocation.proceed()); - TargetSource:封装目标对象,支持单例、原型、请求作用域等不同生命周期的目标对象;
- 暴露代理 :通过
AopContext(ThreadLocal)暴露代理对象,解决内部调用无法触发切面的问题(需设置exposeProxy=true)。
总结
- Spring 动态代理的核心是
AopProxy接口,通过DefaultAopProxyFactory选择 JDK/CGLIB 代理类型; - JDK 代理基于接口和
InvocationHandler,核心是invoke方法 + 拦截器链的责任链执行; - CGLIB 代理基于继承和
MethodInterceptor,核心是intercept方法 +Enhancer生成子类; - 拦截器链的执行是 Spring AOP 的核心,通过
ReflectiveMethodInvocation.proceed()实现通知的有序执行。
掌握以上源码逻辑,就能理解 Spring AOP 的底层实现,以及为什么某些场景下(如内部调用)切面不生效、为什么 final 方法无法被增强等问题。