Spring Boot中@Component与@ConfigurationProperties共存启动报错问题
Spring Boot 3 配置类注入失败问题解决
问题现象
在JDK 19 + Spring 6 + Spring Boot 3.1.0项目中,给CurrencyServiceConfiguration同时添加@Component和@ConfigurationProperties("currency-service")注解,通过@RestController注入该类时项目启动失败,抛出UnsatisfiedDependencyException,日志提示该类被@ConstructorBinding标记但作为普通Bean定义导致依赖注入失败。
错误原因
- 构造函数触发默认
@ConstructorBinding:Spring Boot 3.x版本中,当@ConfigurationProperties注解的类存在带参数的自定义构造函数时,会自动启用@ConstructorBinding模式。此时如果用@Component将其当作普通Bean注册,Spring会尝试从容器中查找构造函数所需的String类型Bean,自然找不到匹配项,导致注入失败。 - 配置文件笔误:
application.properties中重复定义了currency-service.username,正确的应该是currency-service.key=defaultkey,否则key属性无法读取到配置值。
解决方案
方案一:移除自定义构造函数,使用Setter注入(保留@Component)
修改CurrencyServiceConfiguration类,删除带参数的构造函数,添加无参构造函数(Spring需要无参构造实例化Bean,再通过Setter注入配置属性):
package com.ronit.LearnSpringBoot; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties("currency-service") public class CurrencyServiceConfiguration { private String url; private String username; private String key; // 添加无参构造函数 public CurrencyServiceConfiguration() { super(); } public void setUrl(String url) { this.url = url; } public void setUsername(String username) { this.username = username; } public void setKey(String key) { this.key = key; } public String getUrl() { return url; } public String getUsername() { return username; } public String getKey() { return key; } }
方案二:保留构造函数,用配置属性扫描替代@Component
该方案适合需要构造函数注入的场景(更符合不可变对象设计):
- 移除
CurrencyServiceConfiguration上的@Component注解,显式添加@ConstructorBinding(Spring Boot 3.x中带参数构造函数会自动触发该模式,显式标注更清晰):
package com.ronit.LearnSpringBoot; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConstructorBinding; @ConstructorBinding @ConfigurationProperties("currency-service") public class CurrencyServiceConfiguration { private final String url; private final String username; private final String key; // 构造函数注入,属性设为final保证不可变 public CurrencyServiceConfiguration(String url, String username, String key) { this.url = url; this.username = username; this.key = key; } // 仅保留Getter方法,无需Setter public String getUrl() { return url; } public String getUsername() { return username; } public String getKey() { return key; } }
- 在启动类上添加
@ConfigurationPropertiesScan注解,让Spring扫描并注册配置属性类:
package com.ronit.LearnSpringBoot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.ConfigurationPropertiesScan; @SpringBootApplication @ConfigurationPropertiesScan public class LearnSpringBootApplication { public static void main(String[] args) { SpringApplication.run(LearnSpringBootApplication.class, args); } }
也可以用@EnableConfigurationProperties(CurrencyServiceConfiguration.class)替代@ConfigurationPropertiesScan,直接指定要注册的配置类。
修正配置文件笔误
修改application.properties,将重复的username配置改为key:
logging.level.org.springframework = debug currency-service.url=http://default.in28minutes.com currency-service.username=defaultusername currency-service.key=defaultkey
内容的提问来源于stack exchange,提问作者Ronit Pandey
相关产品推荐
相关产品推荐

