Spring依赖注入问题:IndexImplementer未通过自定义无参构造实例化
问题原因分析
1. CGLIB动态代理跳过构造方法调用
如果IndexImplementer被Spring AOP增强(比如标注了@Transactional、@Async,或是被自定义切面切入),Spring默认会用CGLIB生成子类代理。CGLIB默认依赖Objenesis技术直接操作字节码创建实例,这种方式会跳过目标类的构造方法,导致你显式定义的无参构造及内部私有方法都不会执行。
2. 构造方法优先级冲突
如果IndexImplementer除了显式无参构造,还存在带参数的构造方法,且Spring能自动匹配到对应依赖,就可能优先选择带参构造实例化Bean,从而跳过无参构造。
解决方案
针对CGLIB代理场景
方法1:强制CGLIB调用原类构造
在Spring Boot项目中添加以下配置,关闭Objenesis的使用,让CGLIB代理创建实例时必须调用原类的无参构造:
spring.aop.objenesis=false
传统Spring项目可通过自定义DefaultAopProxyFactory,或给ProxyFactory设置setObjenesisEnabled(false)实现相同效果。
方法2:改用JDK动态代理
如果IndexImplementer实现了某个接口,可将Spring AOP代理模式切换为JDK动态代理(默认即为JDK代理,除非手动设置proxy-target-class=true)。JDK代理基于接口生成代理类,不会干扰原类的实例化流程,无参构造会正常执行。
针对构造方法优先级场景
- 若存在多个构造方法,可给无参构造添加
@Autowired(required = false),或用Lombok的@NoArgsConstructor明确指定Spring使用该构造。 - 直接删除不必要的带参构造,确保Spring只能选择你定义的无参构造实例化Bean。
额外验证步骤
- 给
IndexImplementer的无参构造和私有方法添加带调用栈的详细日志,确认是否真的未被调用(避免日志被遗漏)。 - 通过
ApplicationContext.getBean(IndexImplementer.class).getClass()查看Bean类型,若类名带$$EnhancerByCGLIB$$后缀,说明确实是CGLIB代理导致的问题。
内容的提问来源于stack exchange,提问作者cbhutad
相关产品推荐
相关产品推荐

