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

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定义导致依赖注入失败。

错误原因

  1. 构造函数触发默认@ConstructorBinding:Spring Boot 3.x版本中,当@ConfigurationProperties注解的类存在带参数的自定义构造函数时,会自动启用@ConstructorBinding模式。此时如果用@Component将其当作普通Bean注册,Spring会尝试从容器中查找构造函数所需的String类型Bean,自然找不到匹配项,导致注入失败。
  2. 配置文件笔误: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

该方案适合需要构造函数注入的场景(更符合不可变对象设计):

  1. 移除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;
    }
}
  1. 在启动类上添加@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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:03:26