Spring注入Service实例属性为null及new/@Autowired/@PostConstruct初始化时序问题
Spring Bean初始化时序说明
你关注的几个节点的执行顺序如下:
- 实例化Bean:调用类构造方法创建对象,此时所有属性为初始默认值(如引用类型为null)
- 依赖注入:完成
@Autowired等注解标注的属性的注入 - 初始化回调:执行
@PostConstruct标注的方法,此时你代码中的map_khmcKhbh2会完成赋值,启动日志打印也证实了这一步执行正常 - 代理生成:如果该Bean需要被增强(如使用了事务、异步、缓存注解,或者被AOP切面匹配),会生成代理对象替换原生Bean,注入到其他依赖该Bean的位置
问题根因分析
你遇到的返回null和初始化时序无关,完全是CGLIB代理的特性导致:
Spring CGLIB代理的实现是生成目标类的子类作为代理类,这个子类只会重写父类的方法,不会继承也不会同步父类的属性值。你注入的ApiService$$EnhancerBySpringCGLIB$$36288273就是代理类实例,它自身的map_khmcKhbh2属性从来没有被赋值过,直接访问自然返回null。
而调用map_khmcKhbh2()方法时,代理类会将请求转发给它内部持有的原生ApiService实例执行,原生实例的属性已经被@PostConstruct赋值,所以能返回正确值。
你之前观察到的RequestResponseBodyMethodProcessor日志只是表象:当接口返回null时,Spring MVC找不到匹配的消息转换器处理null值,所以会打印supported类型为空的日志,本质还是直接访问代理属性拿到null导致的。
触发CGLIB代理的常见原因
Spring Boot默认开启spring.aop.proxy-target-class=true,只要满足以下任意一种情况就会为Bean生成CGLIB代理:
- ApiService类或其方法上标注了
@Transactional、@Async、@Cacheable等Spring增强注解 - 存在自定义AOP切面匹配到了ApiService的任意方法
解决方案
- 遵循Java开发规范,永远通过getter方法访问Bean的属性,不要直接访问public属性,这是最稳妥的方案
- 如果一定要直接访问属性,排查ApiService上的增强注解和匹配的AOP切面,移除不必要的增强逻辑后,注入的就是原生实例,直接访问属性也能拿到值
内容的提问来源于stack exchange,提问作者ctrlz
相关产品推荐
相关产品推荐

