Spring 动态代理源码深度分析

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]));
    }
}

核心判断逻辑

  1. 如果设置了 proxyTargetClass=true(强制代理类)、目标类无接口,优先用 CGLIB;
  2. 如果目标类是接口 / 已是 JDK 代理类,用 JDK 代理;
  3. 其他情况默认用 JDK 代理。

三、JDK 动态代理源码解析(JdkDynamicAopProxy)

1. 核心实现:invoke 方法

JDK 动态代理基于 java.lang.reflect.ProxyInvocationHandlerJdkDynamicAopProxy 实现了 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

拦截器链的执行核心在 ReflectiveMethodInvocationproceed() 方法(责任链模式):

复制代码
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.EnhancerMethodInterceptor

(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()

六、源码核心关键点

  1. AdvisedSupport:封装了代理的核心配置(目标对象、拦截器、代理类型等),是连接目标对象和代理的桥梁;
  2. 拦截器链 :Spring 将 Advice(通知)转换为 MethodInterceptor,通过责任链模式执行(ReflectiveMethodInvocation.proceed());
  3. TargetSource:封装目标对象,支持单例、原型、请求作用域等不同生命周期的目标对象;
  4. 暴露代理 :通过 AopContext(ThreadLocal)暴露代理对象,解决内部调用无法触发切面的问题(需设置 exposeProxy=true)。

总结

  1. Spring 动态代理的核心是 AopProxy 接口,通过 DefaultAopProxyFactory 选择 JDK/CGLIB 代理类型;
  2. JDK 代理基于接口和 InvocationHandler,核心是 invoke 方法 + 拦截器链的责任链执行;
  3. CGLIB 代理基于继承和 MethodInterceptor,核心是 intercept 方法 + Enhancer 生成子类;
  4. 拦截器链的执行是 Spring AOP 的核心,通过 ReflectiveMethodInvocation.proceed() 实现通知的有序执行。

掌握以上源码逻辑,就能理解 Spring AOP 的底层实现,以及为什么某些场景下(如内部调用)切面不生效、为什么 final 方法无法被增强等问题。

相关推荐
傻啦嘿哟1 小时前
爬虫跑了一小时还没完?换成列表推导式,我提前下班了
java·开发语言·jvm
青槿吖1 小时前
第一篇:Spring面试高频三连问:容器区别|Bean作用域|生命周期,一篇拿捏!
java·开发语言·网络·网络协议·spring·面试·rpc
摇滚侠1 小时前
java: Cannot compile module ‘consumer‘ configured for JVM target 17
java·jvm
带刺的坐椅1 小时前
snack4-jsonpath v4.0.36 发布(支持 IETF RFC 9535 标准)
java·json·jsonpath·snack4
巫山老妖1 小时前
OpenClaw 技术教程大全:从安装到多 Agent 协作,全在这里
java·前端
William_cl1 小时前
ASP.NET Identity 核心实战:注册 / 登录 / 角色管理(避坑指南 + 生活类比)
后端·asp.net·生活
Fox爱分享1 小时前
阿里二面:如何保证 Redis 和 MySQL 的数据一致性?还在背“延时双删”的Sleep玄学?教你高性能 + 高可靠的方案
redis·后端·面试
xiaogg36781 小时前
springboot3+vue3+elementPlus+minio8.2 大文件分片上传
java·spring boot·spring
文心快码 Baidu Comate2 小时前
Comate 4.0的自我进化:后端“0帧起手”写前端、自己修自己!
前端·人工智能·后端·ai编程·文心快码·ai编程助手