利用 Spring Boot 中的 @ConfigurationProperties,優雅綁定配置參數


轉載:程序員自由之路

 

使用 @Value("${property}") 注釋注入配置屬性有時會很麻煩,尤其是當你使用多個屬性或你的數據是分層的時候。

Spring Boot 引入了一個可替換的方案 —— @ConfigurationProperties 來注入屬性。

JavaBean 屬性綁定#

@Data @ConfigurationProperties("my.service") public class MyProperties { // 我們可以簡單地用一個值初始化一個字段來定義一個默認值 private boolean enabled = true; private InetAddress remoteAddress; private final Security security = new Security(); @Data public static class Security { private String username; private String password; // 如果這個屬性配置的話,默認是“USER” private List<String> roles = new ArrayList<>(Collections.singleton("USER")); } } 

在配置文件中進行如下配置:

my: service: enabled: true remoteAddress: 127.0.0.1 security: username: csx password: passwoed roles: - role1 - role2 

最后生成的 Bean 的屬性如下:

{
  "enabled": true, "remoteAddress": "127.0.0.1", "security": { "username": "csx", "password": "passwoed", "roles": [ "role1", "role2" ] } } 

以上的綁定當時需要提供默認的構造函數,以及get/setter方法。

並且不支持 JavaBean 中的靜態成員變量的數據綁定

另外,@ConfigurationProperties 還有兩個其他屬性。

@ConfigurationProperties( value = "my.service", ignoreInvalidFields = false, ignoreUnknownFields = false) 

ignoreInvalidFields:是否忽略非法值,比如將一個字符串 “foo” 賦值給 bool 值,不忽略的話會報啟動異常。

ignoreUnknownFields:對於多余的配置是否會報異常。

構造函數綁定#

有些情況下,我們需要綁定的 JavaBean 是不可變的(防止配置注入 Bean 以后,開發者在程序中錯誤地將配置改掉了)。這種情況下我們可以使用構造函數形式的綁定,只提供 getter 方法。

@Getter @ConstructorBinding @ConfigurationProperties("my.service") public class MyProperties { private boolean enabled; private InetAddress remoteAddress; private final Security security; public MyProperties(boolean enabled, InetAddress remoteAddress, Security security) { this.enabled = enabled; this.remoteAddress = remoteAddress; this.security = security; } @Getter public static class Security { private String username; private String password; private List<String> roles; public Security(String username, String password, @DefaultValue("USER") List<String> roles) { this.username = username; this.password = password; this.roles = roles; } } } 

@DefaultValue 可以指定默認值。

使用構造函數綁定的方式,只能 @EnableConfigurationProperties 或者 @ConfigurationPropertiesScan 的方式激活 Bean。而不能使用 @Component、@Bean 或者 @Import 的方式進行數據綁定。

如果你的類有多個構造函數,可以直接指定使用哪個。

@ConstructorBinding public MyProperties(boolean enabled, InetAddress remoteAddress, Security security) { this.enabled = enabled; this.remoteAddress = remoteAddress; this.security = security; } 

激活方式#

方式一:添加 @Component 注解

上面的方式需要保證 MyProperties 能被 Spring 掃到。

@Data @Component @ConfigurationProperties("my.service") public class MyProperties { } 

方式二:通過 @Bean 方法

@Configuration public class ServiceConfig { @Bean public MyProperties myProperties(){ return new MyProperties(); } } 

方式三:@EnableConfigurationProperties(推薦)

@Configuration @EnableConfigurationProperties(MyProperties.class) public class ServiceConfig { } 

方式四:@ConfigurationPropertiesScan

@SpringBootApplication @ConfigurationPropertiesScan({ "com.example.app", "com.example.another" }) public class MyApplication { } 

怎么使用#

我們通過配置在 Spring 容器中生成了配置 Bean,那么需要怎么使用他們呢?

@Service public class MyService { // 依賴注入 @Autowired private MyProperties properties; public void service(){ System.out.println(properties.getRemoteAddress()); } } @Service public class MyService { private MyProperties properties; // 通過構造函數注入,一般推薦這種方式 public MyService(MyProperties properties) { this.properties = properties; } public void service(){ System.out.println(properties.getRemoteAddress()); } } 

給第三方類綁定值#

假如某些類不是你自己開發的,你也想使用 @ConfigurationProperties 的方式給他綁定值,那么可以進行下面的方式進行配置。

@Configuration(proxyBeanMethods = false) public class ThirdPartyConfiguration { @Bean @ConfigurationProperties(prefix = "another") public AnotherComponent anotherComponent() { return new AnotherComponent(); } } 

寬松綁定原則(Relaxed Binding)#

所謂的寬松綁定原則是指:並不是 JavaBean 中的屬性必須要和配置文件中的一致才能綁定數據,context-path 也能綁定到 contextPath 屬性上。下面舉個列子:

@ConfigurationProperties(prefix = "my.main-project.person") public class MyPersonProperties { private String firstName; public String getFirstName() { return this.firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } } 

下面的幾種方式,都能將配置文件或者環境變量中的值綁定到 firstName 上。

形式 使用場景
my.main-project.person.first-name 推薦使用在 .properties and .yml files.
my.main-project.person.firstName Standard camel case syntax.
my.main-project.person.first_name 推薦使用在 .properties and .yml files.
MY_MAINPROJECT_PERSON_FIRSTNAME 推薦使用在系統環境變量讀取配置時使用

和 @Value 對比#

@Value 是 Spring Framework 中的注解,而 @ConfigurationProperties 是在 Spring Boot 中引入的。

img

參考#

作者:程序員自由之路

出處:https://www.cnblogs.com/54chensongxia/p/15250479.html

版權:本作品采用「署名-非商業性使用-相同方式共享 4.0 國際」許可協議進行許可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM