Autowired 不适用于 Spring 中的 ConfigurationProperties bean
Autowired not working for ConfigurationProperties bean in Spring
我有一个 application.yml 文件,其中包含如下对象列表:
outlook:
mailboxes:
- id: m1
name: mailbox1
- id: m2
name: mailbox2
我创建了一个名为 MailBoxProperties 的 spring 配置 class 以在 bean 中具有这些属性,如下所示:
MailBoxProperties.java
@ConfigurationProperties(prefix = "outlook")
@Configuration
public class MailBoxProperties {
private List<MailBox> mailboxes;
public MailBoxProperties() {
}
public MailBoxProperties(List<MailBox> mailboxes) {
this.mailboxes = mailboxes;
}
public void setMailBoxes(List<MailBox> mailboxes) {
this.mailboxes = mailboxes;
}
public List<MailBox> getMailBoxes() {
return mailboxes;
}
public static class MailBox {
public String getName() {
return this.name;
}
public String getId() {
return this.id;
}
private String id, name;
public MailBox() {
}
public MailBox(String id, String name) {
this.id = id;
this.name = name;
}
}
}
我想将上面的配置 bean 注入到另一个配置 class 中,如下所示:
OutlookConnectionManager.java
@Configuration
@EnableConfigurationProperties
public class OutlookConnectionManager{
@Autowired
private MailBoxProperties mailBoxProperties;
private List<String> names;
@Bean
public OutlookConnectionManager getOutlookConnectionManager() {
OutlookConnectionManager outlookConnectionManager = new OutlookConnectionManager();
outlookConnectionManager.getMailBoxProperties();
return outlookConnectionManager;
}
public void getMailBoxProperties() {
names = new ArrayList<String> ();
for(MailBox mail: mailBoxProperties.getMailBoxes()) {
this.names.add(mail.getName());
}
}
}
但是,MailBoxProperties 始终为空,并且在从 getMailBoxProperties 调用 mailBoxProperties.getMailBoxes() 时抛出空指针异常。
(我试过给@Configuration
@EnableConfigurationProperties(MailBoxProperties.class)。它抛出一个异常,说明创建了 2 个 bean。一个是实际路径,另一个是空路径)。我试过@Import(){MailBoxProperties.class}。
但是,注入在我的主应用程序 class 中完美运行,如下所示:
它获取 bean 并正确打印邮箱名称。
MailApplication.java
@SpringBootApplication
public class MailApplication {
public static void main(String[] args) {
ApplicationContext context = new SpringApplicationBuilder(MailApplication.class).run(args);
MailBoxProperties props = context.getBean(MailBoxProperties.class);
props. getMailBoxes()
.forEach(cc -> System.out.println(cc.getName()));
}
}
我是否遗漏了 OutlookConnectionManager.java 中的任何配置?请帮忙。
注:
我正在使用 Spring boot 1.5.7.RELEASE
谢谢。
正如@m-deinum 指出的那样,属性仍然为空。尝试在用 @PostConstruct
注释的方法中进行初始化。所有自动装配的字段都应该在那个时候填充。
有关 @PostConstruct
的更多详细信息,请点击此处:How to call a method after bean initialization is complete?
我认为您可以解决两件事:
首先,您的 MailBoxProperties
中有一些奇怪的 getter 和 setter 名称(例如 setMailBoxes
字段 mailboxes
应该是 setMailboxes
) 而且我认为 MailBoxProperties 不会从具有自定义 setter 名称的 yaml 文件中获取值。使用默认 getters 和 setters
@ConfigurationProperties("outlook")
public class MailBoxProperties {
private List<MailBox> mailboxes;
public List<MailBox> getMailboxes() {
return mailboxes;
}
public void setMailboxes(List<MailBox> mailboxes) {
this.mailboxes = mailboxes;
}
public static class MailBox {
private String id, name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
其次,我不知道你在 OutlookConnectionManager
的目标是什么,但作为@M。 Deinum 您正试图在 spring 有机会自动连接字段之前调用 getMailBoxProperties
。
而且我认为您可以通过
实现类似的行为
@Component
public class OutlookConnectionManager{
private final MailBoxProperties mailBoxProperties;
private List<String> names;
@Autowired
public OutlookConnectionManager(MailBoxProperties mailBoxProperties) {
this.mailBoxProperties = mailBoxProperties;
this.names = getNames();
}
public List<String> getNames() {
List<String> names = new ArrayList<>();
for(MailBoxProperties.MailBox mail: mailBoxProperties.getMailboxes()) {
names.add(mail.getName());
}
return names;
}
}
基本上你的 MailBoxProperties
应该如@varren 所建议的那样。并且不需要用 @Configuration
注释这个属性 class.
所以 :
@ConfigurationProperties(prefix = "outlook")
public class MailBoxProperties {
private List<MailBox> mailboxes;
public List<MailBox> getMailboxes() {
return mailboxes;
}
public void setMailboxes(List<MailBox> mailboxes) {
this.mailboxes = mailboxes;
}
public static class MailBox {
private String id, name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
然后你可以用 @Configuration
注释你的 OutlookConnectionManager
但是你想在里面做什么有点不正统(你正在重新实例化相同的配置 class new
关键字)。
但是,您可以通过将 @Bean
方法更改为:
来使其工作
OutlookConnectionManager:
@Bean
public OutlookConnectionManager getOutlookConnectionManager() {
OutlookConnectionManager outlookConnectionManager = new OutlookConnectionManager();
//this call will set this.names
this.getMailBoxProperties();
//set this.names to the names variable of outlookConnectionManager instance
outlookConnectionManager.names = this.names;
return outlookConnectionManager;
}
我有一个 application.yml 文件,其中包含如下对象列表:
outlook:
mailboxes:
- id: m1
name: mailbox1
- id: m2
name: mailbox2
我创建了一个名为 MailBoxProperties 的 spring 配置 class 以在 bean 中具有这些属性,如下所示:
MailBoxProperties.java
@ConfigurationProperties(prefix = "outlook")
@Configuration
public class MailBoxProperties {
private List<MailBox> mailboxes;
public MailBoxProperties() {
}
public MailBoxProperties(List<MailBox> mailboxes) {
this.mailboxes = mailboxes;
}
public void setMailBoxes(List<MailBox> mailboxes) {
this.mailboxes = mailboxes;
}
public List<MailBox> getMailBoxes() {
return mailboxes;
}
public static class MailBox {
public String getName() {
return this.name;
}
public String getId() {
return this.id;
}
private String id, name;
public MailBox() {
}
public MailBox(String id, String name) {
this.id = id;
this.name = name;
}
}
}
我想将上面的配置 bean 注入到另一个配置 class 中,如下所示:
OutlookConnectionManager.java
@Configuration
@EnableConfigurationProperties
public class OutlookConnectionManager{
@Autowired
private MailBoxProperties mailBoxProperties;
private List<String> names;
@Bean
public OutlookConnectionManager getOutlookConnectionManager() {
OutlookConnectionManager outlookConnectionManager = new OutlookConnectionManager();
outlookConnectionManager.getMailBoxProperties();
return outlookConnectionManager;
}
public void getMailBoxProperties() {
names = new ArrayList<String> ();
for(MailBox mail: mailBoxProperties.getMailBoxes()) {
this.names.add(mail.getName());
}
}
}
但是,MailBoxProperties 始终为空,并且在从 getMailBoxProperties 调用 mailBoxProperties.getMailBoxes() 时抛出空指针异常。
(我试过给@Configuration @EnableConfigurationProperties(MailBoxProperties.class)。它抛出一个异常,说明创建了 2 个 bean。一个是实际路径,另一个是空路径)。我试过@Import(){MailBoxProperties.class}。
但是,注入在我的主应用程序 class 中完美运行,如下所示: 它获取 bean 并正确打印邮箱名称。
MailApplication.java
@SpringBootApplication
public class MailApplication {
public static void main(String[] args) {
ApplicationContext context = new SpringApplicationBuilder(MailApplication.class).run(args);
MailBoxProperties props = context.getBean(MailBoxProperties.class);
props. getMailBoxes()
.forEach(cc -> System.out.println(cc.getName()));
}
}
我是否遗漏了 OutlookConnectionManager.java 中的任何配置?请帮忙。
注: 我正在使用 Spring boot 1.5.7.RELEASE
谢谢。
正如@m-deinum 指出的那样,属性仍然为空。尝试在用 @PostConstruct
注释的方法中进行初始化。所有自动装配的字段都应该在那个时候填充。
有关 @PostConstruct
的更多详细信息,请点击此处:How to call a method after bean initialization is complete?
我认为您可以解决两件事:
首先,您的 MailBoxProperties
中有一些奇怪的 getter 和 setter 名称(例如 setMailBoxes
字段 mailboxes
应该是 setMailboxes
) 而且我认为 MailBoxProperties 不会从具有自定义 setter 名称的 yaml 文件中获取值。使用默认 getters 和 setters
@ConfigurationProperties("outlook")
public class MailBoxProperties {
private List<MailBox> mailboxes;
public List<MailBox> getMailboxes() {
return mailboxes;
}
public void setMailboxes(List<MailBox> mailboxes) {
this.mailboxes = mailboxes;
}
public static class MailBox {
private String id, name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
其次,我不知道你在 OutlookConnectionManager
的目标是什么,但作为@M。 Deinum getMailBoxProperties
。
而且我认为您可以通过
实现类似的行为@Component
public class OutlookConnectionManager{
private final MailBoxProperties mailBoxProperties;
private List<String> names;
@Autowired
public OutlookConnectionManager(MailBoxProperties mailBoxProperties) {
this.mailBoxProperties = mailBoxProperties;
this.names = getNames();
}
public List<String> getNames() {
List<String> names = new ArrayList<>();
for(MailBoxProperties.MailBox mail: mailBoxProperties.getMailboxes()) {
names.add(mail.getName());
}
return names;
}
}
基本上你的 MailBoxProperties
应该如@varren 所建议的那样。并且不需要用 @Configuration
注释这个属性 class.
所以 :
@ConfigurationProperties(prefix = "outlook")
public class MailBoxProperties {
private List<MailBox> mailboxes;
public List<MailBox> getMailboxes() {
return mailboxes;
}
public void setMailboxes(List<MailBox> mailboxes) {
this.mailboxes = mailboxes;
}
public static class MailBox {
private String id, name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
然后你可以用 @Configuration
注释你的 OutlookConnectionManager
但是你想在里面做什么有点不正统(你正在重新实例化相同的配置 class new
关键字)。
但是,您可以通过将 @Bean
方法更改为:
OutlookConnectionManager:
@Bean
public OutlookConnectionManager getOutlookConnectionManager() {
OutlookConnectionManager outlookConnectionManager = new OutlookConnectionManager();
//this call will set this.names
this.getMailBoxProperties();
//set this.names to the names variable of outlookConnectionManager instance
outlookConnectionManager.names = this.names;
return outlookConnectionManager;
}