但 Spring Boot 提供了另外一種方式 ,可以根據類型校驗和管理application中的bean。 這裏會介紹如何使用@ConfigurationProperties
。
繼續使用mail作例子。配置放在mail.properties文件中。屬性必須命名規範才能綁定成功。舉例:
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!html
Spring Boot 使用一些鬆的規則來綁定屬性到@ConfigurationProperties
bean 而且支持分層結構(hierarchical structure)。
開始建立一個@ConfigurationProperties
bean:web
package com.dxz.property; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(locations = "classpath:mail.properties", ignoreUnknownFields = false, prefix = "mail") public class MailProperties { private String host; private int port; private String from; private String username; private String password; private Smtp smtp; // ... getters and setters public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Smtp getSmtp() { return smtp; } public void setSmtp(Smtp smtp) { this.smtp = smtp; } @Override public String toString() { return "MailProperties [host=" + host + ", port=" + port + ", from=" + from + ", username=" + username + ", password=" + password + ", smtp=" + smtp + "]"; } public static class Smtp { private boolean auth; private boolean starttlsEnable; public boolean isAuth() { return auth; } public void setAuth(boolean auth) { this.auth = auth; } public boolean isStarttlsEnable() { return starttlsEnable; } public void setStarttlsEnable(boolean starttlsEnable) { this.starttlsEnable = starttlsEnable; } } }
以下屬性中建立 ( mail.properties ):spring
mail.host=localhost mail.port=25 mail.smtp.auth=false mail.smtp.starttls-enable=false mail.from=me@localhost mail.username=duan mail.password=duan123456
上例中咱們用@ConfigurationProperties
註解就能夠綁定屬性了。ignoreUnknownFields = false
告訴Spring Boot在有屬性不能匹配到聲明的域的時候拋出異常。開發的時候很方便! prefix
用來選擇哪一個屬性的prefix名字來綁定。
請注意setters 和 getters 須要在@ConfigurationProperties
bean中建立! 與@Value
註解相反。json
咱們須要用屬性來配置 application。 有至少兩種方式來建立@ConfigurationProperties
。便可以搭配@Configuration
註解來提供 @Beans 也能夠單獨使用並注入 @Configuration bean。app
package com.dxz.property3; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(locations = "classpath:mail.properties", ignoreUnknownFields = false, prefix = "mail") public class MailProperties { private String host; private int port; private String from; private String username; private String password; private Smtp smtp; // ... getters and setters public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Smtp getSmtp() { return smtp; } public void setSmtp(Smtp smtp) { this.smtp = smtp; } @Override public String toString() { return "MailProperties [host=" + host + ", port=" + port + ", from=" + from + ", username=" + username + ", password=" + password + ", smtp=" + smtp + "]"; } public static class Smtp { private boolean auth; private boolean starttlsEnable; public boolean isAuth() { return auth; } public void setAuth(boolean auth) { this.auth = auth; } public boolean isStarttlsEnable() { return starttlsEnable; } public void setStarttlsEnable(boolean starttlsEnable) { this.starttlsEnable = starttlsEnable; } } }
啓動及測試類:ide
package com.dxz.property3; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @RestController @SpringBootApplication //@EnableConfigurationProperties(MailProperties.class) public class TestProperty3 { @Autowired private MailProperties mailProperties; @RequestMapping(value = "/hello", method = RequestMethod.GET) @ResponseBody public String hello() { System.out.println("mailProperties" + mailProperties); return "hello world"; } public static void main(String[] args) { //SpringApplication.run(TestProperty1.class, args); new SpringApplicationBuilder(TestProperty3.class).web(true).run(args); } }
結果:spring-boot
mailPropertiesMailProperties [host=localhost, port=25, from=me@localhost, username=duan, password=duan123456, smtp=com.dxz.property3.MailProperties$Smtp@37cebacb]
package com.dxz.property4; public class MailProperties { private String host; private int port; private String from; private String username; private String password; private Smtp smtp; // ... getters and setters public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Smtp getSmtp() { return smtp; } public void setSmtp(Smtp smtp) { this.smtp = smtp; } @Override public String toString() { return "MailProperties [host=" + host + ", port=" + port + ", from=" + from + ", username=" + username + ", password=" + password + ", smtp=" + smtp + "]"; } public static class Smtp { private boolean auth; private boolean starttlsEnable; public boolean isAuth() { return auth; } public void setAuth(boolean auth) { this.auth = auth; } public boolean isStarttlsEnable() { return starttlsEnable; } public void setStarttlsEnable(boolean starttlsEnable) { this.starttlsEnable = starttlsEnable; } } }
配置類(啓動類)測試
package com.dxz.property4; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; @SpringBootApplication public class TestProperty4 { @Bean @ConfigurationProperties(locations = "classpath:mail.properties", prefix = "mail") public MailProperties mailProperties(){ MailProperties mp = new MailProperties(); System.out.println("zheli " + mp); return mp; } public static void main(String[] args) { //SpringApplication.run(TestProperty1.class, args); new SpringApplicationBuilder(TestProperty4.class).web(true).run(args); } }
測試類:ui
package com.dxz.property4; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/task") public class TaskController { @Autowired MailProperties mailProperties; @RequestMapping(value = {"/",""}) public String hellTask(){ System.out.println("mailProperties" +mailProperties); return "hello task !!"; } }
結果:this
咱們和上面例子同樣註解屬性,而後用 Spring的@Autowire
來注入 mail configuration bean:
package com.dxz.property; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(locations = "classpath:mail.properties", ignoreUnknownFields = false, prefix = "mail") public class MailProperties { private String host; private int port; private String from; private String username; private String password; private Smtp smtp; // ... getters and setters public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Smtp getSmtp() { return smtp; } public void setSmtp(Smtp smtp) { this.smtp = smtp; } @Override public String toString() { return "MailProperties [host=" + host + ", port=" + port + ", from=" + from + ", username=" + username + ", password=" + password + ", smtp=" + smtp + "]"; } public static class Smtp { private boolean auth; private boolean starttlsEnable; public boolean isAuth() { return auth; } public void setAuth(boolean auth) { this.auth = auth; } public boolean isStarttlsEnable() { return starttlsEnable; } public void setStarttlsEnable(boolean starttlsEnable) { this.starttlsEnable = starttlsEnable; } } }
啓動類及測試類:
package com.dxz.property; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @RestController @SpringBootApplication @EnableConfigurationProperties(MailProperties.class) public class TestProperty1 { @Autowired private MailProperties mailProperties; @RequestMapping(value = "/hello", method = RequestMethod.GET) @ResponseBody public String hello() { System.out.println("mailProperties" + mailProperties); return "hello world"; } public static void main(String[] args) { //SpringApplication.run(TestProperty1.class, args); new SpringApplicationBuilder(TestProperty1.class).web(true).run(args); } }
結果:
請注意@EnableConfigurationProperties
註解。該註解是用來開啓對@ConfigurationProperties註解配置Bean的支持。也就是@EnableConfigurationProperties註解告訴Spring Boot 能支持@ConfigurationProperties。若是不指定會看到以下異常:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.dxz.property.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時候被發現了。
@ConfigurationProperties
很方便使用。 比用@Value
註解好嗎? 在特定的方案中是的,這只是一個選擇問題。
看下Spring Boot的文檔有更多的關於 typesafe configuration 屬性
通常在咱們開發中,經過IDE打開屬性文件會產生一個自動提示。這種自定義提示也可使用到咱們自定義配置類中。
首先咱們須要在項目中加入processor jar包
dependencies { compileOnly "org.springframework.boot:spring-boot-configuration-processor" }
第二步咱們須要配置META-INF/spring-configuration-metadata.json文件來描述。可是代碼量挺大的,爲了方便咱們能夠經過IDE來生成,這裏使用的是idea。
在idea設置中搜索Annotation Processors,接下來勾住Enable annonation processing就完成了。
咱們能夠在編譯後的文件中看到自動生成的spring-configuration-metadata.json。
附上配圖: