但 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。
附上配图: