AOP 原理深剖:动态代理与 CGLIB 字节码增强

🔍 AOP 原理深剖:动态代理与 CGLIB 字节码增强

文章目录

  • [🔍 AOP 原理深剖:动态代理与 CGLIB 字节码增强](#🔍 AOP 原理深剖:动态代理与 CGLIB 字节码增强)
  • [🎯 一、AOP 本质:基于代理的横切逻辑织入](#🎯 一、AOP 本质:基于代理的横切逻辑织入)
    • [🔄 AOP 核心概念解析](#🔄 AOP 核心概念解析)
    • [💡 代理模式在 AOP 中的应用](#💡 代理模式在 AOP 中的应用)
  • [⚡ 二、JDK 动态代理机制深度解析](#⚡ 二、JDK 动态代理机制深度解析)
    • [🔧 JDK 动态代理核心原理](#🔧 JDK 动态代理核心原理)
    • [💻 JDK 动态代理实现机制](#💻 JDK 动态代理实现机制)
    • [🛠️ Spring 中的 JDK 动态代理实现](#🛠️ Spring 中的 JDK 动态代理实现)
    • [📊 生成的代理类字节码分析](#📊 生成的代理类字节码分析)
  • [🚀 三、CGLIB 子类代理机制详解](#🚀 三、CGLIB 子类代理机制详解)
    • [🔧 CGLIB 字节码增强原理](#🔧 CGLIB 字节码增强原理)
    • [💻 CGLIB 字节码生成机制](#💻 CGLIB 字节码生成机制)
    • [🛠️ Spring 中的 CGLIB 代理实现](#🛠️ Spring 中的 CGLIB 代理实现)
    • [📊 CGLIB 生成的子类字节码分析](#📊 CGLIB 生成的子类字节码分析)
  • [⚖️ 四、性能与限制差异对比分析](#⚖️ 四、性能与限制差异对比分析)
    • [📊 技术特性对比表](#📊 技术特性对比表)
    • [📈 性能测试数据](#📈 性能测试数据)
    • [🔧 Spring 代理选择策略](#🔧 Spring 代理选择策略)
  • [🔍 五、源码追踪:代理创建核心流程](#🔍 五、源码追踪:代理创建核心流程)
    • [🏗️ AbstractAutoProxyCreator 核心机制](#🏗️ AbstractAutoProxyCreator 核心机制)
    • [⚙️ ProxyFactory 代理创建流程](#⚙️ ProxyFactory 代理创建流程)
    • [📋 AdvisedSupport 配置信息管理](#📋 AdvisedSupport 配置信息管理)
  • [🔄 六、代理链执行机制详解](#🔄 六、代理链执行机制详解)
    • [🎯 拦截器链执行流程](#🎯 拦截器链执行流程)
  • [💡 ReflectiveMethodInvocation 核心实现](#💡 ReflectiveMethodInvocation 核心实现)
    • [🏗️ 拦截器链构建过程](#🏗️ 拦截器链构建过程)
  • [💻 七、实战:自定义日志切面与调试](#💻 七、实战:自定义日志切面与调试)
    • [🛠️ 自定义日志切面实现](#🛠️ 自定义日志切面实现)
  • [🔍 代理对象调试与分析](#🔍 代理对象调试与分析)
  • [📝 AOP 配置与测试类](#📝 AOP 配置与测试类)
    • [📊 预期调试输出](#📊 预期调试输出)

🎯 一、AOP 本质:基于代理的横切逻辑织入

🔄 AOP 核心概念解析

​​AOP 专业术语体系​​
AOP核心概念 切面 Aspect 连接点 Joinpoint 切点 Pointcut 通知 Advice 目标对象 Target 代理对象 Proxy 横切关注点模块化 程序执行点 匹配连接点的谓词 切面在连接点的动作 被代理的原始对象 增强后的代理对象

💡 代理模式在 AOP 中的应用

​​AOP 代理机制核心原理​​

java 复制代码
// AOP 代理的抽象表示
public interface AopProxy {
    
    // 创建代理对象
    Object getProxy();
    Object getProxy(ClassLoader classLoader);
}

// 代理工厂接口
public interface ProxyFactory {
    
    // 设置目标对象
    void setTarget(Object target);
    
    // 添加通知(增强逻辑)
    void addAdvice(Advice advice);
    
    // 创建代理
    Object getProxy();
}

​​传统编程 vs AOP 编程对比​​:

java 复制代码
// 传统方式:横切逻辑与业务代码耦合
@Service
public class UserService {
    
    public User findUser(Long id) {
        // 横切关注点:日志记录
        log.info("开始查询用户: {}", id);
        long startTime = System.currentTimeMillis();
        
        try {
            // 核心业务逻辑
            User user = userRepository.findById(id);
            
            // 横切关注点:性能监控
            long costTime = System.currentTimeMillis() - startTime;
            log.info("用户查询完成,耗时: {}ms", costTime);
            
            return user;
        } catch (Exception e) {
            // 横切关注点:异常处理
            log.error("用户查询失败", e);
            throw e;
        }
    }
}

// AOP方式:关注点分离
@Service
public class CleanUserService {
    
    public User findUser(Long id) {
        // 纯净的业务逻辑
        return userRepository.findById(id);
    }
}

// 横切逻辑通过切面实现
@Aspect
@Component
public class LoggingAspect {
    
    @Around("execution(* com.example.service.*.*(..))")
    public Object logMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable {
        // 统一的横切逻辑
        log.info("开始执行: {}", joinPoint.getSignature());
        long startTime = System.currentTimeMillis();
        
        try {
            Object result = joinPoint.proceed();
            long costTime = System.currentTimeMillis() - startTime;
            log.info("执行完成,耗时: {}ms", costTime);
            return result;
        } catch (Exception e) {
            log.error("执行失败", e);
            throw e;
        }
    }
}

⚡ 二、JDK 动态代理机制深度解析

🔧 JDK 动态代理核心原理

​​JDK 动态代理类图结构​​:
<<interface>> InvocationHandler +invoke(proxy, method, args) : Object Proxy +newProxyInstance(ClassLoader, Class[]?, InvocationHandler) : Object +getInvocationHandler(Object) : InvocationHandler +isProxyClass(Class) : boolean JdkDynamicAopProxy -targetSource : TargetSource -advisors : List<Advisor> +getProxy() : Object +invoke(Object, Method, Object[]?) : Object

💻 JDK 动态代理实现机制

​​核心源码分析​​:

java 复制代码
// java.lang.reflect.Proxy 关键源码
public class Proxy implements java.io.Serializable {
    
    // 代理类生成入口
    public static Object newProxyInstance(ClassLoader loader,
                                        Class<?>[] interfaces,
                                        InvocationHandler h) {
        // 1. 安全检查
        Objects.requireNonNull(h);
        final Class<?>[] intfs = interfaces.clone();
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }

        // 2. 查找或生成代理类
        Class<?> cl = getProxyClass0(loader, intfs);

        // 3. 使用指定InvocationHandler调用构造函数
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }

            final Constructor<?> cons = cl.getConstructor(constructorParams);
            return newInstance(cons, h);
            
        } catch (IllegalAccessException|InstantiationException e) {
            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else {
                throw new InternalError(t.toString(), t);
            }
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString(), e);
        }
    }
    
    // 代理类缓存机制
    private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
    
    // 代理类生成工厂
    private static final class ProxyClassFactory
        implements BiFunction<ClassLoader, Class<?>[], Class<?>> {
        
        // 所有代理类名称前缀
        private static final String proxyClassNamePrefix = "$Proxy";
        
        // 下一个生成的代理类编号
        private static final AtomicLong nextUniqueNumber = new AtomicLong();
        
        @Override
        public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
            Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
            
            // 验证接口
            for (Class<?> intf : interfaces) {
                // 确保类加载器一致
                Class<?> interfaceClass = null;
                try {
                    interfaceClass = Class.forName(intf.getName(), false, loader);
                } catch (ClassNotFoundException e) {
                }
                if (interfaceClass != intf) {
                    throw new IllegalArgumentException(
                        intf + " is not visible from class loader");
                }
                
                // 验证是否为接口
                if (!interfaceClass.isInterface()) {
                    throw new IllegalArgumentException(
                        interfaceClass.getName() + " is not an interface");
                }
                
                // 验证接口是否重复
                if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
                    throw new IllegalArgumentException(
                        "repeated interface: " + interfaceClass.getName());
                }
            }
            
            // 生成代理类名称
            String proxyName = proxyPkg + proxyClassNamePrefix + nextUniqueNumber.getAndIncrement();
            
            // 生成代理类字节码
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);
            try {
                // 定义代理类
                return defineClass0(loader, proxyName,
                                  proxyClassFile, 0, proxyClassFile.length);
            } catch (ClassFormatError e) {
                throw new IllegalArgumentException(e.toString());
            }
        }
    }
}

🛠️ Spring 中的 JDK 动态代理实现

​​JdkDynamicAopProxy 核心实现​​:

java 复制代码
// Spring JdkDynamicAopProxy 源码分析
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
    
    private final AdvisedSupport advised;
    private final Class<?>[] proxiedInterfaces;
    
    public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
        this.advised = config;
        this.proxiedInterfaces = config.getProxiedInterfaces();
    }
    
    @Override
    public Object getProxy() {
        return getProxy(ClassUtils.getDefaultClassLoader());
    }
    
    @Override
    public Object getProxy(ClassLoader classLoader) {
        // 生成代理类
        return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
    }
    
    // InvocationHandler 接口实现 - 核心拦截逻辑
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object retVal;
        
        // 1. 获取目标对象
        TargetSource targetSource = this.advised.getTargetSource();
        Object target = targetSource.getTarget();
        
        try {
            // 2. 检查是否需要拦截(如equals、hashCode等方法)
            if (!this.advised.opaque && 
                method.getDeclaringClass().isInterface() &&
                method.getDeclaringClass() != Object.class) {
                
                // 3. 获取方法拦截器链
                List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, target.getClass());
                
                // 4. 如果没有拦截器,直接调用目标方法
                if (chain.isEmpty()) {
                    retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
                } else {
                    // 5. 创建方法调用并执行拦截器链
                    MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, target.getClass(), chain);
                    retVal = invocation.proceed();
                }
            } else {
                // 6. 内部方法直接调用
                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
            }
            
            return retVal;
            
        } finally {
            if (target != null && !targetSource.isStatic()) {
                targetSource.releaseTarget(target);
            }
        }
    }
}

📊 生成的代理类字节码分析

​​反编译生成的代理类示例​​:

java 复制代码
// 生成的代理类大致结构(通过反编译工具查看)
public final class $Proxy0 extends Proxy implements UserService {
    
    private static Method m1;  // hashCode()
    private static Method m2;  // equals()
    private static Method m3;  // toString()
    private static Method m4;  // findUser()
    
    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("hashCode");
            m2 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m3 = Class.forName("java.lang.Object").getMethod("toString");
            m4 = Class.forName("com.example.UserService").getMethod("findUser", Long.class);
        } catch (Exception e) {
            throw new Error(e);
        }
    }
    
    public $Proxy0(InvocationHandler h) {
        super(h);
    }
    
    public final User findUser(Long id) {
        try {
            // 调用InvocationHandler的invoke方法
            return (User) super.h.invoke(this, m4, new Object[]{id});
        } catch (RuntimeException e) {
            throw e;
        } catch (Throwable e) {
            throw new UndeclaredThrowableException(e);
        }
    }
    
    public final int hashCode() {
        try {
            return (Integer) super.h.invoke(this, m1, null);
        } catch (RuntimeException e) {
            throw e;
        } catch (Throwable e) {
            throw new UndeclaredThrowableException(e);
        }
    }
    
    // 其他方法类似...
}

🚀 三、CGLIB 子类代理机制详解

🔧 CGLIB 字节码增强原理

​​CGLIB 核心组件架构​​:
Enhancer +setSuperclass(Class) : void +setCallback(Callback) : void +setCallbacks(Callback[]) : void +create() : Object <<interface>> MethodInterceptor +intercept(Object, Method, Object[]?, MethodProxy) : Object MethodProxy +invoke(Object, Object[]?) : Object +invokeSuper(Object, Object[]?) : Object CglibAopProxy -advised : AdvisedSupport +getProxy() : Object

💻 CGLIB 字节码生成机制

​​Enhancer 核心源码分析​​:

java 复制代码
// CGLIB Enhancer 字节码生成流程
public class Enhancer extends AbstractClassGenerator {
    
    private Class superclass;
    private Class[] interfaces;
    private CallbackFilter callbackFilter;
    private Callback[] callbacks;
    
    // 创建代理对象
    public Object create() {
        // 1. 设置默认回调类型
        classOnly = false;
        argumentTypes = null;
        return createHelper();
    }
    
    private Object createHelper() {
        // 2. 验证配置
        preValidate();
        
        // 3. 生成代理类
        Object key = KEY_FACTORY.newInstance(
            superclass != null ? superclass.getName() : null,
            ReflectUtils.getNames(interfaces),
            filter == ALL_ZERO ? null : new WeakCacheKey<CallbackFilter>(filter),
            callbackTypes,
            useFactory,
            interceptDuringConstruction,
            serialVersionUID);
        
        // 4. 使用缓存机制
        return super.create(key);
    }
    
    // 字节码生成核心方法
    protected Object generate(Object key) {
        // 5. 生成代理类字节码
        ClassLoader loader = getClassLoader();
        Map<ClassLoader, ClassLoaderData> cache = CACHE;
        ClassLoaderData data = cache.get(loader);
        
        if (data == null) {
            synchronized (AbstractClassGenerator.class) {
                cache = CACHE;
                data = cache.get(loader);
                if (data == null) {
                    Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
                    data = new ClassLoaderData(loader);
                    newCache.put(loader, data);
                    CACHE = newCache;
                }
            }
        }
        
        // 6. 生成字节码
        byte[] b = strategy.generate(this);
        
        // 7. 定义类
        Class gen = ReflectUtils.defineClass(genClassName, b, loader);
        
        // 8. 实例化代理对象
        return firstInstance(gen);
    }
}

🛠️ Spring 中的 CGLIB 代理实现

​​CglibAopProxy 核心实现​​:

java 复制代码
// Spring CglibAopProxy 源码分析
class CglibAopProxy implements AopProxy {
    
    private final AdvisedSupport advised;
    private Object[] constructorArgs;
    private Class<?>[] constructorArgTypes;
    
    public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
        this.advised = config;
    }
    
    @Override
    public Object getProxy() {
        return getProxy(null);
    }
    
    @Override
    public Object getProxy(ClassLoader classLoader) {
        // 1. 创建Enhancer实例
        Enhancer enhancer = createEnhancer();
        
        // 2. 配置类加载器
        if (classLoader != null) {
            enhancer.setClassLoader(classLoader);
        }
        
        // 3. 设置超类(目标类)
        enhancer.setSuperclass(this.advised.getTargetClass());
        
        // 4. 设置接口(如果需要)
        enhancer.setInterfaces(this.advised.getProxiedInterfaces());
        
        // 5. 设置回调
        Callback[] callbacks = getCallbacks(this.advised.getTargetClass());
        enhancer.setCallbacks(callbacks);
        
        // 6. 设置回调过滤器
        enhancer.setCallbackFilter(new ProxyCallbackFilter());
        
        // 7. 创建代理实例
        return createProxyClassAndInstance(enhancer, callbacks);
    }
    
    private Callback[] getCallbacks(Class<?> rootClass) {
        // 创建回调数组
        Callback[] callbacks = new Callback[5];
        
        // 1. 方法拦截器(核心拦截逻辑)
        callbacks[0] = new DynamicAdvisedInterceptor(this.advised);
        
        // 2. 直接调用目标方法(用于equals、hashCode等)
        callbacks[1] = new DirectCallInterceptor();
        
        // 3. 其他回调...
        return callbacks;
    }
    
    // 动态建议拦截器(核心拦截逻辑)
    private static class DynamicAdvisedInterceptor implements MethodInterceptor {
        
        private final AdvisedSupport advised;
        
        public DynamicAdvisedInterceptor(AdvisedSupport advised) {
            this.advised = advised;
        }
        
        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            Object retVal;
            
            // 1. 获取目标对象
            TargetSource targetSource = this.advised.getTargetSource();
            Object target = targetSource.getTarget();
            
            try {
                // 2. 获取拦截器链
                List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, target.getClass());
                
                // 3. 执行拦截逻辑
                if (chain.isEmpty()) {
                    // 直接调用目标方法
                    retVal = methodProxy.invoke(target, args);
                } else {
                    // 创建CGLIB方法调用并执行拦截器链
                    CglibMethodInvocation invocation = new CglibMethodInvocation(
                        proxy, target, method, args, target.getClass(), chain, methodProxy);
                    retVal = invocation.proceed();
                }
                
                return retVal;
                
            } finally {
                if (target != null && !targetSource.isStatic()) {
                    targetSource.releaseTarget(target);
                }
            }
        }
    }
}

📊 CGLIB 生成的子类字节码分析

​​CGLIB 代理类结构示例​​:

java 复制代码
// 生成的CGLIB代理类大致结构
public class UserService$$EnhancerByCGLIB$$12345678 extends UserService {
    
    private MethodInterceptor interceptor;
    private static final Method CGLIB$findUser$0$Method;
    private static final MethodProxy CGLIB$findUser$0$Proxy;
    
    static {
        // 初始化方法和代理引用
        CGLIB$findUser$0$Method = ReflectUtils.findMethod("findUser", UserService.class, Long.class);
        CGLIB$findUser$0$Proxy = MethodProxy.create(UserService.class, UserService$$EnhancerByCGLIB$$12345678.class, 
                                                   "()V", "findUser", "CGLIB$findUser$0");
    }
    
    public User findUser(Long id) {
        // 调用拦截器
        return (User) interceptor.intercept(this, CGLIB$findUser$0$Method, new Object[]{id}, CGLIB$findUser$0$Proxy);
    }
    
    // 直接调用父类方法(绕过拦截)
    final User CGLIB$findUser$0(Long id) {
        return super.findUser(id);
    }
    
    // 其他增强方法...
}

⚖️ 四、性能与限制差异对比分析

📊 技术特性对比表

​​JDK 动态代理 vs CGLIB 详细对比​​:

特性维度 JDK 动态代理 CGLIB 字节码增强 优劣分析 / 工程建议
代理机制 基于 java.lang.reflect.Proxy,通过接口代理 基于 ASM 字节码生成,创建目标类的子类 CGLIB 可代理具体类,JDK 只能代理接口
底层原理 运行时生成 $Proxy 类,拦截接口方法 通过 ASM 动态生成字节码,创建子类并重写方法 JDK 依赖反射调用,CGLIB 基于字节码操作
性能表现 反射调用略慢,生成快 初次生成慢,调用快(ASM直连调用) 小规模短生命周期服务建议用 JDK,长期高频调用建议用 CGLIB
内存占用 较小,轻量级代理类 较大,需缓存字节码 JDK 代理内存友好,CGLIB 需注意 PermGen/Metaspace 占用
限制条件 必须实现接口 无需接口,但不能代理 final 类/方法 无接口类只能使用 CGLIB
兼容性 原生 JDK 支持 依赖第三方库(spring-core 内置 CGLIB) JDK 代理通用性更强
调试友好性 生成类名清晰,如 $Proxy0 类名复杂,如 OrderService$$EnhancerBySpringCGLIB$$abc123 JDK 代理更易定位堆栈问题
AOP 场景 默认用于有接口的 Bean 用于无接口的 Bean Spring 自动选择:有接口用 JDK,无接口用 CGLIB
创建速度 快速反射生成 需字节码编译生成 CGLIB 初次创建耗时更高
可维护性 JDK 原生 API,兼容性强 ASM 升级需适配不同 JDK 版本 大规模项目推荐保持默认策略
代理类命名示例 $Proxy4 UserService$$EnhancerBySpringCGLIB$$3a8e12 JDK 更直观,CGLIB 更底层

📈 性能测试数据

​​性能基准测试代码​​:

java 复制代码
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
public class ProxyPerformanceTest {
    
    private UserService jdkProxy;
    private UserService cglibProxy;
    private UserService target;
    
    @Setup
    public void setup() {
        // 目标对象
        target = new UserServiceImpl();
        
        // 创建JDK代理
        jdkProxy = (UserService) Proxy.newProxyInstance(
            getClass().getClassLoader(),
            new Class[]{UserService.class},
            new LoggingInvocationHandler(target));
        
        // 创建CGLIB代理
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(UserServiceImpl.class);
        enhancer.setCallback(new LoggingMethodInterceptor(target));
        cglibProxy = (UserService) enhancer.create();
    }
    
    @Benchmark
    public void testDirectCall() {
        target.findUser(1L);
    }
    
    @Benchmark
    public void testJdkProxy() {
        jdkProxy.findUser(1L);
    }
    
    @Benchmark
    public void testCglibProxy() {
        cglibProxy.findUser(1L);
    }
    
    // 测试结果示例(纳秒级别)
    // DirectCall: 150 ns/op
    // JDK Proxy: 450 ns/op (3倍开销)
    // CGLIB: 280 ns/op (1.8倍开销)
}

🔧 Spring 代理选择策略

​​DefaultAopProxyFactory 代理选择逻辑​​:

java 复制代码
public class DefaultAopProxyFactory implements AopProxyFactory {
    
    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        // 1. 检查配置选项
        if (config.isOptimize() || config.isProxyTargetClass() || 
            hasNoUserSuppliedProxyInterfaces(config)) {
            
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class");
            }
            
            // 2. 判断是否适合CGLIB代理
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                // 接口或JDK代理类使用JDK代理
                return new JdkDynamicAopProxy(config);
            }
            
            // 3. 使用CGLIB代理
            return new ObjenesisCglibAopProxy(config);
        } else {
            // 4. 使用JDK代理
            return new JdkDynamicAopProxy(config);
        }
    }
    
    private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
        Class<?>[] interfaces = config.getProxiedInterfaces();
        return (interfaces.length == 0 || 
                (interfaces.length == 1 && interfaces[0].equals(SpringProxy.class)));
    }
}

🔍 五、源码追踪:代理创建核心流程

🏗️ AbstractAutoProxyCreator 核心机制

​​自动代理创建器工作流程​​:

java 复制代码
// AbstractAutoProxyCreator 源码分析
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
    implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            
            // 检查是否需要创建代理
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }
    
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        // 1. 检查是否已处理
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        
        // 2. 检查是否需要跳过代理
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        
        // 3. 检查是否是基础设施类或需要跳过的类
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
        
        // 4. 获取适用的通知(增强逻辑)
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            
            // 5. 创建代理对象
            Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }
        
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
    
    protected Object createProxy(Class<?> beanClass, String beanName, 
                                Object[] specificInterceptors, TargetSource targetSource) {
        
        // 1. 创建ProxyFactory
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);
        
        // 2. 配置代理目标
        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            } else {
                // 评估接口
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
        
        // 3. 构建 Advisor 数组
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
        
        // 4. 设置目标源
        proxyFactory.setTargetSource(targetSource);
        
        // 5. 自定义代理工厂
        customizeProxyFactory(proxyFactory);
        
        // 6. 创建代理实例
        return proxyFactory.getProxy(getProxyClassLoader());
    }
}

⚙️ ProxyFactory 代理创建流程

​​ProxyFactory 代理生成机制​​:

java 复制代码
public class ProxyFactory extends ProxyCreatorSupport {
    
    public Object getProxy() {
        return createAopProxy().getProxy();
    }
    
    public Object getProxy(ClassLoader classLoader) {
        return createAopProxy().getProxy(classLoader);
    }
    
    protected final AopProxy createAopProxy() {
        return getAopProxyFactory().createAopProxy(this);
    }
}

// ProxyCreatorSupport 配置管理
public class ProxyCreatorSupport extends AdvisedSupport {
    
    private AopProxyFactory aopProxyFactory;
    
    public ProxyCreatorSupport() {
        this.aopProxyFactory = new DefaultAopProxyFactory();
    }
    
    // 获取AOP代理工厂
    public AopProxyFactory getAopProxyFactory() {
        return this.aopProxyFactory;
    }
}

📋 AdvisedSupport 配置信息管理

​​代理配置信息容器​​:

java 复制代码
public class AdvisedSupport extends ProxyConfig implements Advised {
    
    // 目标源
    private TargetSource targetSource;
    
    // 目标接口
    private Class<?>[] interfaces;
    
    // 顾问(Advisor)列表
    private List<Advisor> advisors = new ArrayList<>();
    
    // 顾问链工厂
    private AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();
    
    // 获取方法拦截器链
    public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
        MethodCacheKey cacheKey = new MethodCacheKey(method);
        List<Object> cached = this.methodCache.get(cacheKey);
        
        if (cached == null) {
            // 通过顾问链工厂获取拦截器
            cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
                this, method, targetClass);
            this.methodCache.put(cacheKey, cached);
        }
        return cached;
    }
}

🔄 六、代理链执行机制详解

🎯 拦截器链执行流程

​​方法调用拦截时序图​​:
Client Proxy MethodInvocation Interceptor1 Interceptor2 Target 调用代理方法 创建MethodInvocation 调用intercept() 前置处理逻辑 调用proceed() 调用proceed() → 最终调用目标方法 返回结果 返回结果 后置处理逻辑 返回最终结果 返回结果 返回方法结果 Client Proxy MethodInvocation Interceptor1 Interceptor2 Target

💡 ReflectiveMethodInvocation 核心实现

​​方法调用链执行源码​​:

java 复制代码
public class ReflectiveMethodInvocation implements ProxyMethodInvocation {
    
    protected final Object proxy;
    protected final Object target;
    protected final Method method;
    protected final Object[] arguments;
    private final Class<?> targetClass;
    private final List<Object> interceptorsAndDynamicMethodMatchers;
    private int currentInterceptorIndex = -1;
    
    public ReflectiveMethodInvocation(Object proxy, Object target, Method method, 
                                     Object[] arguments, Class<?> targetClass,
                                     List<Object> interceptorsAndDynamicMethodMatchers) {
        this.proxy = proxy;
        this.target = target;
        this.method = method;
        this.arguments = arguments;
        this.targetClass = targetClass;
        this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
    }
    
    @Override
    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 InterceptorAndDynamicMethodMatcher) {
            InterceptorAndDynamicMethodMatcher dm =
                (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
            if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
                return dm.interceptor.invoke(this);
            } else {
                // 跳过当前拦截器,继续执行下一个
                return proceed();
            }
        } else {
            // 4. 普通拦截器调用
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }
    
    // 调用目标方法(最终执行)
    protected Object invokeJoinpoint() throws Throwable {
        return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
    }
}

🏗️ 拦截器链构建过程

​​DefaultAdvisorChainFactory 拦截器链构建​​:

java 复制代码
public class DefaultAdvisorChainFactory implements AdvisorChainFactory {
    
    @Override
    public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
            Advised config, Method method, Class<?> targetClass) {
        
        List<Object> interceptorList = new ArrayList<>(config.getAdvisors().length);
        Class<?> actualClass = targetClass;
        
        // 1. 获取所有顾问
        Advisor[] advisors = config.getAdvisors();
        for (Advisor advisor : advisors) {
            if (advisor instanceof PointcutAdvisor) {
                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
                
                // 2. 检查切点是否匹配
                if (pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
                    MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                    
                    // 3. 检查方法是否匹配
                    if (mm.matches(method, actualClass)) {
                        MethodInterceptor[] interceptors = 
                            registry.getInterceptors(advisor);
                        
                        if (mm.isRuntime()) {
                            // 4. 动态匹配器,需要运行时参数
                            for (MethodInterceptor interceptor : interceptors) {
                                interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                            }
                        } else {
                            // 5. 静态匹配器,直接添加拦截器
                            interceptorList.addAll(Arrays.asList(interceptors));
                        }
                    }
                }
            }
        }
        
        return interceptorList;
    }
}

💻 七、实战:自定义日志切面与调试

🛠️ 自定义日志切面实现

​​完整的日志切面示例​​:

java 复制代码
@Aspect
@Component
@Slf4j
public class ComprehensiveLoggingAspect {
    
    // 切点定义:匹配Service层所有方法
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceLayer() {}
    
    // 切点定义:匹配Dao层所有方法
    @Pointcut("execution(* com.example.dao.*.*(..))")
    public void daoLayer() {}
    
    // 切点定义:匹配Controller层所有方法
    @Pointcut("execution(* com.example.controller.*.*(..))")
    public void controllerLayer() {}
    
    // 组合切点:业务层方法
    @Pointcut("serviceLayer() || daoLayer()")
    public void businessLayer() {}
    
    // 前置通知:方法执行前记录日志
    @Before("businessLayer()")
    public void logBeforeMethod(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        String className = joinPoint.getTarget().getClass().getSimpleName();
        Object[] args = joinPoint.getArgs();
        
        log.info("🏁 开始执行: {}.{}()", className, methodName);
        log.debug("📋 方法参数: {}", Arrays.toString(args));
    }
    
    // 后置通知:方法执行后记录日志(无论是否异常)
    @After("businessLayer()")
    public void logAfterMethod(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        String className = joinPoint.getTarget().getClass().getSimpleName();
        
        log.info("✅ 执行完成: {}.{}()", className, methodName);
    }
    
    // 返回后通知:记录返回值
    @AfterReturning(pointcut = "businessLayer()", returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        String methodName = joinPoint.getSignature().getName();
        
        if (result != null) {
            log.debug("📤 方法返回: {} -> {}", methodName, 
                     result instanceof Collection ? ((Collection) result).size() + "条记录" : result);
        } else {
            log.debug("📤 方法返回: {} -> null", methodName);
        }
    }
    
    // 异常通知:记录异常信息
    @AfterThrowing(pointcut = "businessLayer()", throwing = "ex")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable ex) {
        String methodName = joinPoint.getSignature().getName();
        String className = joinPoint.getTarget().getClass().getSimpleName();
        
        log.error("❌ 方法执行异常: {}.{}() - {}", className, methodName, ex.getMessage(), ex);
    }
    
    // 环绕通知:性能监控和耗时统计
    @Around("businessLayer()")
    public Object logAroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        String methodName = joinPoint.getSignature().getName();
        String className = joinPoint.getTarget().getClass().getSimpleName();
        
        long startTime = System.currentTimeMillis();
        boolean success = false;
        
        try {
            log.debug("⏱️ 开始计时: {}.{}()", className, methodName);
            
            // 执行目标方法
            Object result = joinPoint.proceed();
            success = true;
            
            return result;
            
        } finally {
            long endTime = System.currentTimeMillis();
            long costTime = endTime - startTime;
            
            String status = success ? "成功" : "失败";
            if (costTime > 1000) {
                log.warn("🐌 方法执行较慢: {}.{}() {},耗时: {}ms", className, methodName, status, costTime);
            } else {
                log.debug("⚡ 方法执行: {}.{}() {},耗时: {}ms", className, methodName, status, costTime);
            }
        }
    }
}

🔍 代理对象调试与分析

​​代理对象调试工具类​​:

java 复制代码
@Component
@Slf4j
public class ProxyDebugUtil {
    
    /**
     * 分析代理对象类型和结构
     */
    public static void analyzeProxy(Object bean, String beanName) {
        log.info("🔍 开始分析Bean: {}", beanName);
        
        Class<?> beanClass = bean.getClass();
        log.info("📊 Bean实际类型: {}", beanClass.getName());
        
        // 检查是否是代理对象
        if (isJdkProxy(bean)) {
            log.info("🔧 代理类型: JDK动态代理");
            analyzeJdkProxy(bean);
        } else if (isCglibProxy(bean)) {
            log.info("🔧 代理类型: CGLIB代理");
            analyzeCglibProxy(bean);
        } else {
            log.info("🔧 代理类型: 非代理对象(原始Bean)");
        }
        
        // 输出类层次结构
        logClassHierarchy(beanClass);
    }
    
    /**
     * 判断是否是JDK代理
     */
    private static boolean isJdkProxy(Object bean) {
        return bean instanceof java.lang.reflect.Proxy;
    }
    
    /**
     * 判断是否是CGLIB代理
     */
    private static boolean isCglibProxy(Object bean) {
        return bean.getClass().getName().contains("$$EnhancerByCGLIB$$");
    }
    
    /**
     * 分析JDK代理结构
     */
    private static void analyzeJdkProxy(Object proxy) {
        try {
            InvocationHandler handler = Proxy.getInvocationHandler(proxy);
            log.info("🎯 InvocationHandler类型: {}", handler.getClass().getName());
            
            Class<?>[] interfaces = proxy.getClass().getInterfaces();
            log.info("📋 代理接口数量: {}", interfaces.length);
            for (Class<?> intf : interfaces) {
                log.info("   - {}", intf.getName());
            }
        } catch (Exception e) {
            log.error("分析JDK代理失败", e);
        }
    }
    
    /**
     * 分析CGLIB代理结构
     */
    private static void analyzeCglibProxy(Object proxy) {
        Class<?> proxyClass = proxy.getClass();
        Class<?> superClass = proxyClass.getSuperclass();
        log.info("👨‍👦 父类: {}", superClass.getName());
        
        // 分析回调字段
        try {
            Field callbackField = proxyClass.getDeclaredField("CGLIB$CALLBACK_0");
            callbackField.setAccessible(true);
            Object callback = callbackField.get(proxy);
            log.info("🔄 回调处理器: {}", callback.getClass().getName());
        } catch (Exception e) {
            log.debug("无法获取CGLIB回调字段: {}", e.getMessage());
        }
    }
    
    /**
     * 输出类层次结构
     */
    private static void logClassHierarchy(Class<?> clazz) {
        log.info("🏗️ 类层次结构:");
        Class<?> current = clazz;
        int level = 0;
        
        while (current != null && current != Object.class) {
            String indent = "  ".repeat(level);
            log.info("{}└── {}", indent, current.getName());
            current = current.getSuperclass();
            level++;
        }
    }
    
    /**
     * 检查方法拦截情况
     */
    public static void checkMethodInterception(Object proxy, String methodName) {
        try {
            Method method = proxy.getClass().getMethod(methodName);
            log.info("🎯 方法拦截检查: {}", methodName);
            log.info("📝 方法声明类: {}", method.getDeclaringClass().getName());
            
            // 检查方法上的注解
            Annotation[] annotations = method.getAnnotations();
            log.info("🏷️ 方法注解数量: {}", annotations.length);
            for (Annotation ann : annotations) {
                log.info("   - @{}", ann.annotationType().getSimpleName());
            }
        } catch (Exception e) {
            log.error("方法检查失败", e);
        }
    }
}

📝 AOP 配置与测试类

AOP 配置类​​:

java 复制代码
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true) // 强制使用CGLIB代理
@Slf4j
public class AopConfig {
    
    @Bean
    public UserService userService() {
        return new UserServiceImpl();
    }
    
    @Bean
    public OrderService orderService() {
        return new OrderServiceImpl();
    }
    
    @Bean
    public ComprehensiveLoggingAspect loggingAspect() {
        return new ComprehensiveLoggingAspect();
    }
    
    @Bean
    public ProxyDebugUtil proxyDebugUtil() {
        return new ProxyDebugUtil();
    }
}

​​测试与调试类​​:

java 复制代码
@SpringBootTest
@Slf4j
public class AopDebugTest {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private OrderService orderService;
    
    @Autowired
    private ProxyDebugUtil proxyDebugUtil;
    
    @Test
    public void testProxyAnalysis() {
        log.info("=== 开始代理对象分析 ===");
        
        // 分析UserService代理
        proxyDebugUtil.analyzeProxy(userService, "userService");
        proxyDebugUtil.checkMethodInterception(userService, "findUser");
        
        log.info("---");
        
        // 分析OrderService代理
        proxyDebugUtil.analyzeProxy(orderService, "orderService");
        proxyDebugUtil.checkMethodInterception(orderService, "createOrder");
    }
    
    @Test
    public void testAopExecution() {
        log.info("=== 开始AOP执行测试 ===");
        
        // 测试方法调用
        User user = userService.findUser(1L);
        log.info("查询用户结果: {}", user);
        
        Order order = orderService.createOrder(new OrderRequest(1L, 100.0));
        log.info("创建订单结果: {}", order);
    }
    
    @Test
    public void testPerformanceComparison() {
        log.info("=== 开始性能对比测试 ===");
        
        int iterations = 10000;
        
        // 测试直接调用
        long directStart = System.currentTimeMillis();
        for (int i = 0; i < iterations; i++) {
            userService.findUser((long) i);
        }
        long directTime = System.currentTimeMillis() - directStart;
        
        // 测试代理调用
        long proxyStart = System.currentTimeMillis();
        for (int i = 0; i < iterations; i++) {
            userService.findUser((long) i);
        }
        long proxyTime = System.currentTimeMillis() - proxyStart;
        
        log.info("性能测试结果:");
        log.info("直接调用耗时: {}ms", directTime);
        log.info("代理调用耗时: {}ms", proxyTime);
        log.info("性能开销: {}%", (proxyTime - directTime) * 100.0 / directTime);
    }
}

📊 预期调试输出

​​代理分析输出示例​​:

log 复制代码
=== 开始代理对象分析 ===
🔍 开始分析Bean: userService
📊 Bean实际类型: com.example.UserServiceImpl$$EnhancerByCGLIB$$12345678
🔧 代理类型: CGLIB代理
👨‍👦 父类: com.example.UserServiceImpl
🔄 回调处理器: org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor
🏗️ 类层次结构:
└── com.example.UserServiceImpl$$EnhancerByCGLIB$$12345678
  └── com.example.UserServiceImpl
    └── java.lang.Object
🎯 方法拦截检查: findUser
📝 方法声明类: com.example.UserServiceImpl
🏷️ 方法注解数量: 0

​​AOP执行日志输出​​:

log 复制代码
=== 开始AOP执行测试 ===
🏁 开始执行: UserServiceImpl.findUser()
📋 方法参数: [1]
⏱️ 开始计时: UserServiceImpl.findUser()
✅ 执行完成: UserServiceImpl.findUser()
📤 方法返回: findUser -> User{id=1, name='test'}
⚡ 方法执行: UserServiceImpl.findUser() 成功,耗时: 15ms
查询用户结果: User{id=1, name='test'}
相关推荐
2401_837088506 小时前
ResponseEntity - Spring框架的“标准回复模板“
java·前端·spring
lang201509286 小时前
Spring Boot RSocket:高性能异步通信实战
java·spring boot·后端
默默coding的程序猿6 小时前
1.北京三维天地公司-实施实习生
java·sql·技术支持·面经·实施·实施工程师·三维天地
天天摸鱼的java工程师7 小时前
解释 Spring 框架中 bean 的生命周期:一个八年 Java 开发的实战视角
java·后端
尤老师FPGA7 小时前
LVDS系列32:Xilinx 7系 ADC LVDS接口参考设计(三)
android·java·ui
自由的疯7 小时前
Java 如何学习 Jenkins?
java·架构
自由的疯7 小时前
Java ‌认识Docker
java·架构
Forfun_tt7 小时前
xss-labs pass-10
java·前端·xss
又是忙碌的一天7 小时前
java基础 -----底层
java·基础