You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Java反射访问Spring Cglib增强类中的成员字段

问题原因

你遇到的空值问题是CGLIB代理的特性导致的:

  • CGLIB通过继承目标类的方式生成代理子类,代理类实例本身不会继承/持有父类的字段值
  • 原始Controller的所有属性、业务逻辑都保存在代理对象内部持有的目标对象实例中,你直接从代理对象反射读取父类字段,拿到的自然是未赋值的null
解决方案

通过Spring提供的AOP工具类先获取代理背后的原始目标对象,再对目标对象做反射操作即可,同时需要给私有字段设置可访问权限。
修改后的完整代码如下:

import org.springframework.aop.Advised;
import org.springframework.aop.AopUtils;
import org.springframework.stereotype.Component;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.RestController;

@Component
public class TestProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        var annotation = AnnotationUtils.findAnnotation(bean.getClass(), RestController.class);
        if (annotation != null) {
            System.out.println("IM HERE");
            if (UserController.class.isAssignableFrom(AopUtils.getTargetClass(bean))) {
                try {
                    // 递归获取最内层的原始目标对象,兼容多层代理场景
                    Object targetBean = bean;
                    while (AopUtils.isAopProxy(targetBean) && targetBean instanceof Advised) {
                        targetBean = ((Advised) targetBean).getTargetSource().getTarget();
                    }
                    // 直接从目标类获取字段
                    var f = UserController.class.getDeclaredField("service");
                    // 私有字段需要设置可访问权限
                    f.setAccessible(true);
                    var obj = f.get(targetBean);
                    System.out.println(obj);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return bean;
        }
        return bean;
    }
}
注意事项
  • 该实现依赖Spring AOP模块,常规Spring/Spring Boot Web项目都已默认引入,无需额外加依赖
  • 如果项目开启了CGLIB代理的类缓存,拿到目标对象的逻辑不会产生额外性能开销
  • 反射操作完成后不需要手动改回setAccessible(false),JDK会自动回收该反射对象的访问权限配置

内容的提问来源于stack exchange,提问作者Goncalo Condeco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 05:24:04