2

我有一个 application.yml 文件,其中包含如下对象列表:

outlook:
  mailboxes:
    - id: m1
      name: mailbox1

    - id: m2
      name: mailbox2

我创建了一个名为MailBoxProperties的 spring 配置类,以便在 bean 中具有这些属性,如下所示:

邮箱属性.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 注入到另一个配置类中,如下所示:

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。一个带有实际路径,另一个带有null)。我试过@Import(){MailBoxProperties.class}。

但是,注入在我的主应用程序类中完美运行,如下所示:它获取 bean 并正确打印邮箱名称。

邮件应用程序.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

谢谢你。

4

3 回答 3

2

基本上你MailBoxProperties应该像@varren 建议的那样。并且不需要用@Configuration这个属性类进行注释。

所以 :

@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;
        }
    }
}

然后你可以保留你的OutlookConnectionManager注释,@Configuration但你想在里面做什么有点不正统(你正在用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;
}
于 2017-09-19T18:27:27.453 回答
0

正如@m-deinum 指出的那样,属性仍然为空。尝试在带有注释的方法中进行初始化@PostConstruct。所有自动装配的字段都应由该点填充。

@PostConstruct有关此处的更多详细信息: bean初始化完成后如何调用方法?

于 2017-09-19T18:11:07.820 回答
0

我认为你可以解决两件事:


首先,您的MailBoxProperties(例如setMailBoxesfor field mailboxesshould be setMailboxes)中有一些奇怪的 getter 和 setter 名称,我认为 MailBoxProperties 不会从带有自定义 setter 名称的 yaml 文件中获取值。使用默认的 getter 和 setter

@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在 spring 有机会自动连接字段之前打电话。

我认为你可以实现类似的行为

@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;
    }
}
于 2017-09-19T18:12:42.553 回答