Java Spring无法自动注入构造函数参数

Java Spring无法自动注入构造函数参数,java,spring,spring-boot,dependency-injection,configuration,Java,Spring,Spring Boot,Dependency Injection,Configuration,我是一个完全的Spring初学者,我正在尝试使用Spring引导进行基本配置。我希望尽可能使用构造函数注入。然而,Spring抛出了我不理解的异常。为了便于阅读,我缩短了有问题的代码: 我的配置YAML文件(类路径上有snake YAML): 申请代码: package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigur

我是一个完全的Spring初学者,我正在尝试使用Spring引导进行基本配置。我希望尽可能使用构造函数注入。然而,Spring抛出了我不理解的异常。为了便于阅读,我缩短了有问题的代码:

我的配置YAML文件(类路径上有snake YAML):

申请代码:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    private final DBProperties dbProperties;
    DBProperties getDbProperties() {
        return dbProperties;
    }

    public DemoApplication(DBProperties dbProperties) {
        this.dbProperties = dbProperties;
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
以及Spring未能正确连接的类:

package com.example.demo;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;

@ConfigurationProperties(prefix = "database")
@Component
public class DBProperties {
    private final List<ConnectionProperties> activeJdbcConnections;
    private int inactiveTimeout;

    // ERROR: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'int' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    public DBProperties(List<ConnectionProperties> activeJdbcConnections, int inactiveTimeout) {
        this.activeJdbcConnections = activeJdbcConnections;
        this.inactiveTimeout = inactiveTimeout;
    }

    public List<ConnectionProperties> getActiveJdbcConnections() {
        return activeJdbcConnections;
    }

    public int getInactiveTimeout() {
        return inactiveTimeout;
    }

    @Component
    public static class ConnectionProperties {
        private String name;

        // ERROR: Parameter 0 of constructor in com.example.demo.DBProperties$ConnectionProperties required a bean of type 'java.lang.String' that could not be found.
        public ConnectionProperties(String name){
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }
}
package com.example.demo;
导入org.springframework.boot.context.properties.ConfigurationProperties;
导入org.springframework.stereotype.Component;
导入java.util.List;
@配置属性(前缀=“数据库”)
@组成部分
公共类DBProperties{
私有最终列表activeJdbcConnections;
私人int不活动超时;
//错误:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有类型为“int”的符合条件的bean可用:至少需要1个符合autowire候选条件的bean。依赖项批注:{}
公共数据库属性(列出activeJdbcConnections,int-inactiveTimeout){
this.activeJdbcConnections=activeJdbcConnections;
this.inactiveTimeout=inactiveTimeout;
}
公共列表getActiveJdbcConnections(){
返回activeJdbcConnections;
}
public int getInactivateTimeout(){
返回不活动超时;
}
@组成部分
公共静态类ConnectionProperties{
私有字符串名称;
//错误:com.example.demo.DBProperties$ConnectionProperties中构造函数的参数0需要找不到类型为“java.lang.String”的bean。
公共连接属性(字符串名称){
this.name=名称;
}
公共字符串getName(){
返回名称;
}
}
}
有两个不同的错误。首先,在
DBProperties
构造函数中,Spring无法连接整数
inactiveTimeout
,即使它连接参数
activeJdbcConnections
没有问题。这可以使用@Value参数解决,但这是不可取的,因为@Value无法识别@ConfigurationParameters指定的前缀,因此必须为每个@Value注释重复前缀

其次,Spring无法连接
ConnectionProperties
name
参数。如果添加了setter,Spring可以使用它,但如上所述,我希望使用构造函数注入。由于参数的名称与我想要连接的属性匹配,我不理解这里的问题。顺便说一句,我无法用@Value注释解决这个问题,因为我不知道从当前列表元素指定属性的语法


如何让Spring使用构造函数注入正确实例化配置类?

我认为您的方法存在一些问题。首先,您不能定义int和String类型的bean(即使您尝试在某个地方定义它们),因此名称和inactiveTimeout将永远无法作为bean通过构造函数注入自动连接

其次,@组件在扫描时默认是Spring单例bean,这意味着每个Spring上下文只有一个实例。如果将ConnectionProperties作为组件传递到DBProperties构造函数的列表中,那么它就没有意义了,因为只有一个已安装的ConnectionProperties,所以它只是一个简短的列表

如果您希望DBProperties是一个bean,其构造函数中提供了一些参数,那么您可能希望直接将其定义为@bean并自己调用构造函数。Spring无法计算出要在其中输入的参数!比如:

@Bean
public DBProperties dbProperties() {
    ...
    return new DBProperties(myArray, myNumber);
}
然后,这个DBProperties bean将可用于在Spring引导应用程序的任何其他地方注入构造函数

@Bean
public DBProperties dbProperties() {
    ...
    return new DBProperties(myArray, myNumber);
}