找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2941

积分

0

好友

411

主题
发表于 2025-12-10 03:51:50 | 查看: 59| 回复: 0

在基于Spring框架的开发中,你是否思考过:为何一个简单的 @Aspect 注解就能让方法拥有拦截能力?其背后的动态代理机制是如何运作的?本文将深入 CglibAopProxy 的源码,从代理对象的生成到方法拦截的完整链路,逐层剖析,帮助你彻底理解 Spring AOP 的核心实现原理。

一、CglibAopProxy 的核心角色:代理对象的创建入口

Spring AOP 的代理机制主要有两种实现:基于接口的 JDK 动态代理和基于继承的 CGLIB 代理。当目标类未实现任何接口时,Spring 默认会选用 CglibAopProxy。整个过程的起点是 ProxyFactorygetProxy() 方法,它是获取代理对象的统一入口。

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

此处的 dynamicAdvisedInterceptorDynamicAdvisedInterceptor 类型的一个实例,它作为 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 时序图清晰地描述了各组件间的交互:

alt

六、总结:CglibAopProxy 的底层逻辑剖析

Spring CglibAopProxy 的实现逻辑可以清晰地归纳为三个核心步骤:

  1. 生成代理对象:利用 CGLIB 的 Enhancer 为目标类创建动态子类,并将 DynamicAdvisedInterceptor 设置为统一的回调拦截器。
  2. 方法拦截:代理对象上的任何方法调用都会被 DynamicAdvisedInterceptor.intercept() 捕获,并获取对应的增强器链。
  3. 链式执行:通过 MethodInvocation.proceed() 方法递归执行增强链中的每个拦截器,最终调用原始目标方法完成业务逻辑。

本质上,Spring AOP 的魔法并不复杂,其核心是在运行时通过动态代理技术生成新类,并将横切关注点(增强逻辑)以链式调用的方式“编织”到原有方法调用流程中。深入理解 CglibAopProxy 的源码,是掌握 Spring AOP架构原理和进行高效问题排查的关键。




上一篇:Java try...catch性能深度解析:误区澄清与实战优化指南
下一篇:2025年Q3金融AI前沿论文解读:量化投资新模型与趋势洞察
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-6 11:25 , Processed in 0.291051 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表