但 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!

Spring Boot 使用一些松的规则来绑定属性到​​@ConfigurationProperties​​ bean 并且支持分层结构(hierarchical structure)。

开始创建一个​​@ConfigurationProperties​​ bean:

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

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

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类


如下属性中创建 ( mail.properties ):

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

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

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

上例中我们用​​@ConfigurationProperties​​注解就可以绑定属性了。​​ignoreUnknownFields = false​​告诉Spring Boot在有属性不能匹配到声明的域的时候抛出异常。开发的时候很方便! ​​prefix​​ 用来选择哪个属性的prefix名字来绑定。

请注意setters 和 getters 需要在​​@ConfigurationProperties​​ bean中创建! 与​​@Value​​注解相反。


我们需要用属性来配置 application。 有至少两种方式来创建​​@ConfigurationProperties​​​。即可以搭配​​@Configuration​​ 注解来提供 @Beans 也可以单独使用并注入 @Configuration bean。

方案1:定义spring的一个实体bean装载配置文件信息,其它要使用配置信息是注入该实体bean

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

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

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

启动及测试类:

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

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中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

结果:


mailPropertiesMailProperties [host=localhost, port=25, from=me@localhost, username=duan, password=duan123456, smtp=com.dxz.property3.MailProperties$Smtp@37cebacb]


方案2:@Bean+@ConfigurationProperties

我们还可以把@ConfigurationProperties还可以直接定义在@bean的注解上,这是bean实体类就不用@Component和@ConfigurationProperties了

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

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

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

配置类(启动类)

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

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

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

测试类:

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

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 !!"; }  }

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

结果:

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_html_15


方案3:@ConfigurationProperties + @EnableConfigurationProperties

我们和上面例子一样注解属性,然后用 Spring的​​@Autowire​​来注入 mail configuration bean:

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

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

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

启动类及测试类:

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

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

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类

结果:

在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties_测试类_20

请注意​@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 属性​