Spring构造器注入报No default constructor found错误
问题产生原因
- 直接触发点:你在
HomeController、ProductService类中仅定义了注入依赖用的有参构造方法,没有定义无参构造方法,Spring容器实例化Bean时找不到默认无参构造,就会抛出No default constructor found和NoSuchMethodException错误。 - 核心版本适配问题:Spring 4.3 版本才新增了单构造器隐式注入特性——也就是当类只定义了一个有参构造时,不需要显式标注
@Autowired,容器会自动识别这个构造方法完成参数注入。如果你使用的是低于4.3的Spring版本(传统SSM项目集成的老版本Spring非常常见),又没有给有参构造显式加@Autowired,容器就不会把这个有参构造作为Bean实例化的入口,只会默认去找无参构造。 - 额外触发场景:如果你的传统Spring Web项目使用老版本CGLIB生成动态代理(比如没有面向接口写代理、配置了强制CGLIB代理),老版本CGLIB生成代理子类时必须调用父类的无参构造方法,没有无参构造也会抛出同类异常。
修复方案
按推荐优先级排序选择即可:
- 方案1(全版本兼容,最稳妥):给所有构造器注入的类的有参构造方法,显式加上
@Autowired注解,不需要额外写无参构造。
示例代码:
按照同样的规则给@Controller public class HomeController { // 依赖设置为final,保证不可变 private final ProductService productService; // 显式标注构造器为注入入口 @Autowired public HomeController(ProductService productService) { this.productService = productService; } // 原有请求映射方法保持不变 }ProductService类的有参构造也加上@Autowired注解即可,不需要修改Repository层的配置,Spring Data JPA会自动为继承JpaRepository的接口生成实现Bean。 - 方案2(适合Spring 4.3+版本):如果确认项目Spring版本在4.3及以上,优先检查两个配置:
- 确认组件扫描的包路径覆盖了
HomeController、ProductService所在的包路径,避免因为依赖Bean没被扫描到,导致构造器参数匹配失败 - 升级Spring内置的CGLIB依赖到对应版本,新版本CGLIB已经支持带参构造的代理类生成,不需要强制要求目标类提供无参构造
- 确认组件扫描的包路径覆盖了
- 方案3(不推荐,仅兜底兼容):给每个组件类补充无参构造方法,将构造器注入改为setter注入或者字段注入,但这种方式无法保证依赖的不可变性,容易出现NPE空指针问题,违背构造器注入的设计初衷。
内容的提问来源于stack exchange,提问作者user1712
相关产品推荐
相关产品推荐

