我是一个完整的Spring初学者,我正在尝试使用Spring Boot进行基本配置。我想尽可能使用构造函数注入。但是,Spring正在抛出我不理解的异常。我缩短了有问题的代码以便于阅读:
我的配置YAML文件(我在类路径上有蛇yaml):
database:
inactive_timeout: 100
active_jdbc_connections:
# this is a list with one property in each element
- name: foo
- name: bar
- name: baz
- name: qux
申请代码:
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;
}
}
}
有两个单独的错误。首先,在DBProperties
构造函数中,Spring无法连接整数inactiveTimeout
,即使它在连接参数activeJdbcConnections
时也没有问题。这可以使用@Value参数来解决,但这是不可取的,因为@Value不能识别@ConfigurationParameters指定的前缀,因此必须为每个@Value注释重复前缀。
其次,Spring无法连接name
的{{1}}参数。如果添加了Spring,Spring可以使用setter,但如上所述,我想使用构造函数注入。由于参数的名称与我想要连接的属性匹配,我不明白这里的问题。作为旁注,我无法用@Value注释来解决这个问题,因为我不知道从当前列表元素中指定属性的语法。
如何让Spring使用构造函数注入来正确实例化我的配置类?
答案 0 :(得分:1)
我认为您的方法存在一些问题。首先,您不能定义int和String类型的bean(即使您尝试在某处定义它们),因此名称和inactiveTimeout将永远不可用作通过构造函数注入自动装配的bean。
其次,@Components在扫描时默认为Spring单例bean,这意味着每个Spring上下文只有一个实例。如果你将它传递给DBProperties构造函数的列表,那么将ConnectionProperties作为一个组件就没那么有意义,因为只有一个实例化的ConnectionProperties,所以它有点像一个短列表!
如果您希望DBProperties是一个在其构造函数中提供了一些参数的bean,那么您可能希望直接将其定义为@Bean并自己调用构造函数。 Spring无法确定你想要放在哪里的参数!类似的东西:
@Bean
public DBProperties dbProperties() {
...
return new DBProperties(myArray, myNumber);
}
然后,这个DBProperties bean可以在Spring启动应用程序的其他任何地方注入Constructor。