上一篇博客寫了 如何在Spring Boot application中配置mail . 使用 @Value 注解注入屬性. 但 Spring Boot 提供了另一種方式 ,能夠根據(jù)類型校驗和管理application中的bean。 這里會介紹如何使用@ConfigurationProperties。
繼續(xù)使用mail做例子。配置放在mail.properties文件中。屬性必須命名規(guī)范才能綁定成功。舉例:
1 protocol and PROTOCOL will be bind to protocol field of a bean
2 smtp-auth , smtp_auth , smtpAuth will be bind to smtpAuth field of a bean
3 smtp.auth will be bind to … hmm to smtp.auth field of a bean!
Spring Boot 使用一些松的規(guī)則來綁定屬性到@ConfigurationProperties bean 并且支持分層結(jié)構(gòu)(hierarchical structure)。
開始創(chuàng)建一個@ConfigurationProperties bean:
@ConfigurationProperties(locations = "classpath:mail.properties",
ignoreUnknownFields = false,
prefix = "mail")
public class MailProperties {
public static class Smtp {
private boolean auth;
private boolean starttlsEnable;
// ... getters and setters
}
@NotBlank private String host;
private int port;
private String from;
private String username;
private String password;
@NotNull private Smtp smtp;
// ... getters and setters
}
…從如下屬性中創(chuàng)建 ( mail.properties ):
mail.host=localhost
mail.port=25
mail.smtp.auth=false
mail.smtp.starttls-enable=false
mail.from=me@localhost
mail.username=
mail.password=
上例中我們用@ConfigurationProperties注解就可以綁定屬性了。ignoreUnknownFields = false告訴Spring Boot在有屬性不能匹配到聲明的域的時候拋出異常。開發(fā)的時候很方便! prefix 用來選擇哪個屬性的prefix名字來綁定。
請注意setters 和 getters 需要在@ConfigurationProperties bean中創(chuàng)建! 與@Value注解相反, 這帶來了代碼中的一些困擾 (特別是簡單的業(yè)務(wù)中,個人觀點).
OK,但是我們需要用屬性來配置 application. 有至少兩種方式來創(chuàng)建@ConfigurationProperties。即可以搭配@Configuration 注解來提供 @Beans 也可以單獨使用并注入 @Configuration bean。
方案1:
@Configuration
@ConfigurationProperties(locations = "classpath:mail.properties",
prefix = "mail")
public class MailConfiguration {
public static class Smtp {
private boolean auth;
private boolean starttlsEnable;
// ... getters and setters
}
@NotBlank private String host;
private int port;
private String from;
private String username;
private String password;
@NotNull private Smtp smtp;
// ... getters and setters
@Bean public JavaMailSender javaMailSender() {
// omitted for readability
}
}
方案2
我們和上面例子一樣注解屬性,然后用 Spring的@Autowire來注入 mail configuration bean:
@Configuration
@EnableConfigurationProperties(MailProperties.class)
public class MailConfiguration {
@Autowired private MailProperties mailProperties;
@Bean public JavaMailSender javaMailSender() {
// omitted for readability
}
}
請注意@EnableConfigurationProperties注解。 這個注解告訴Spring Boot 使能支持@ConfigurationProperties。如果不指定會看到如下異常:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [demo.mail.MailProperties] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
注意: 還有其他辦法 (Spring Boot 總是有其他辦法!) 讓@ConfigurationProperties beans 被添加 – 用@Configuration或者 @Component注解, 這樣就可以在 component scan時候被發(fā)現(xiàn)了。
總結(jié):
@ConfigurationProperties很方便使用。 比用@Value注解好嗎? 在特定的方案中是的,這只是一個選擇問題。
看下Spring Boot的文檔有更多的關(guān)于 typesafe configuration 屬性