@ConfigurationProperties的使用
@ConfigurationProperties標(biāo)簽可以把.yml文件里的配置讀取到類里
比如,我需要把釘釘小程序的app-key和app-secret放在application.yml文件里面,方便我的配置,那么我們就這樣在application.yml里編寫:
dingding: app-key: "dings9oi56464654gfqrfms" app-secret: "58786163213546161231321231321aAhbCa8Vw2EVBJiw9_96vd"
現(xiàn)在我們新建一個(gè)類,使用注解
@ConfigurationProperties
來(lái)獲得這些值:
@Setter @Getter @ConfigurationProperties(prefix = "dingding") public class AppInfoConfigProperties { private String APP_KEY; private String APP_SECRET; }
注意,被 @ConfigurationProperties 修飾的類必須帶有set方法,否則無(wú)法獲得配置值。
這樣一來(lái),AppInfoConfigProperties就可以拿到application.yml里的配置,這里的匹配是寬松匹配,寫成
private String appKey; private String appSecret;
也是可以獲取到值的。
在經(jīng)過(guò)以上的步驟后,AppInfoConfigProperties本身并沒(méi)有加入容器,也就拿不到他的值,下一步我們把它注冊(cè)成一個(gè)Bean:
@EnableConfigurationProperties(AppInfoConfigProperties.class) @Configuration public class AppInfoConfig { @Autowired AppInfoConfigProperties appInfoConfigProperties; @Bean("appInfoUtil") public AppInfoUtil appInfoUtil(){ return new AppInfoUtil(appInfoConfigProperties.getAPP_KEY(),appInfoConfigProperties.getAPP_SECRET()); } }
這里我們使用了 @EnableConfigurationProperties(AppInfoConfigProperties.class) 來(lái)將 AppInfoConfigProperties給注冊(cè)到了容器里,同時(shí)通過(guò) @Autowired拿到了它的值。
至此,application.yml文件中的值已被成功獲取到了容器里。
以下是AppInfoUtil 的結(jié)構(gòu):
@Getter @Setter @AllArgsConstructor public class AppInfoUtil { private String appKey; private String appSecret; @Override public String toString() { return String.format("本小程序的APP-KEY:[%s];本小程序的APP-SECRET:[%s]",this.getAppKey(),this.getAppSecret()); } }
為什么不直接使用AppInfoConfigProperties?
原因是因?yàn)锳ppInfoUtil可能會(huì)根據(jù)業(yè)務(wù)的需要做出很多的增強(qiáng)功能,所以與配置分離。
注解@ConfigurationProperties使用方法
最近在思考使用java config的方式進(jìn)行配置,java config是指基于java配置的spring。傳統(tǒng)的Spring一般都是基本xml配置的,后來(lái)spring3.0新增了許多java config的注解,特別是spring boot,基本都是清一色的java config。
Spring配置方式
第一階段:xml配置
在spring 1.x時(shí)代,使用spring開發(fā)滿眼都是xml配置的bean,隨著項(xiàng)目的擴(kuò)大,
我們需要把xml配置文件分放到不同的配置文件中,那時(shí)候需要頻繁地在開發(fā)的類和配置文件間切換。
第二階段:注解配置
在spring 2.x時(shí)代,隨著JDK1.5帶來(lái)的注解支持,spring提供了聲明bean的注解,大大減少了配置量。這時(shí)spring圈子存在一種爭(zhēng)論:注解配置和xml配置究竟哪個(gè)更好?我們最終的選擇是應(yīng)用的基本配置用xml,業(yè)務(wù)配置用戶注解。
第三階段:Java配置(java config)
從spring 3.x到現(xiàn)在,spring提供了Java配置的能力,使用Java配置更好的理解
配置的bean。spring 4.x和spring boot都推薦使用Java配置。
Spring IOC有一個(gè)非常核心的概念――Bean。由Spring容器來(lái)負(fù)責(zé)對(duì)Bean的實(shí)例化,裝配和管理。XML是用來(lái)描述Bean最為流行的配置方式。但隨著Spring的日益發(fā)展,越來(lái)越多的人對(duì)Spring提出了批評(píng)。“Spring項(xiàng)目大量的爛用XML”就是最為嚴(yán)勵(lì)的一個(gè)批評(píng)。由于Spring會(huì)把幾乎所有的業(yè)務(wù)類都以Bean的形式配置在XML文件中,造成了大量的XML文件。使用XML來(lái)配置Bean失去了編譯時(shí)的類型安全檢查。大量的XML配置使得整個(gè)項(xiàng)目變得更加復(fù)雜。
隨著JAVA EE 5.0的發(fā)布,其中引入了一個(gè)非常重要的特性――Annotations(注釋)。注釋是源代碼的標(biāo)簽,這些標(biāo)簽可以在源代碼層進(jìn)行處理或通過(guò)編譯器把它熔入到class文件中。在JAVA EE5以后的版本中,注釋成為了一個(gè)主要的配置選項(xiàng)。Spring使用注釋來(lái)描述Bean的配置與采用XML相比,因類注釋是在一個(gè)類源代碼中,可以獲得類型安全檢查的好處。可以良好的支持重構(gòu)。
JavaConfig就是使用注釋來(lái)描述Bean配置的組件。JavaConfig 是Spring的一個(gè)子項(xiàng)目, 比起Spring,它還是一個(gè)非常年青的項(xiàng)目。目前的版本是1.0 M2。使用XML來(lái)配置Bean所能實(shí)現(xiàn)的功能,通過(guò)JavaConfig同樣可以很好的實(shí)現(xiàn)。
下面具體講一講@ConfigurationProperties使用方法
@ConfigurationProperties
Spring源碼中大量使用了ConfigurationProperties注解,比如server.port就是由該注解獲取到的,通過(guò)與其他注解配合使用,能夠?qū)崿F(xiàn)Bean的按需配置。
該注解有一個(gè)prefix屬性,通過(guò)指定的前綴,綁定配置文件中的配置,該注解可以放在類上,也可以放在方法上
可以從注解說(shuō)明中看到,當(dāng)將該注解作用于方法上時(shí),如果想要有效的綁定配置,那么該方法需要有@Bean注解且所屬Class需要有@Configuration注解。
簡(jiǎn)單一句話概括就是:Sring的有效運(yùn)行是通過(guò)上下文(Bean容器)中Bean的配合完成的,Bean可以簡(jiǎn)單理解成對(duì)象,有些對(duì)象需要指定字段內(nèi)容,那么這些內(nèi)容我們可以通過(guò)配置文件進(jìn)行綁定,然后將此Bean歸還給容器
作用于方法
比較常見的就是配置讀寫分離的場(chǎng)景。
配置文件內(nèi)容
#數(shù)據(jù)源 spring.datasource.druid.write.url=jdbc:mysql://localhost:3306/jpa spring.datasource.druid.write.username=root spring.datasource.druid.write.password=1 spring.datasource.druid.write.driver-class-name=com.mysql.jdbc.Driver spring.datasource.druid.read.url=jdbc:mysql://localhost:3306/jpa spring.datasource.druid.read.username=root spring.datasource.druid.read.password=1 spring.datasource.druid.read.driver-class-name=com.mysql.jdbc.Driver
java代碼
@Configuration public class DruidDataSourceConfig { /** * DataSource 配置 * @return */ @ConfigurationProperties(prefix = "spring.datasource.druid.read") @Bean(name = "readDruidDataSource") public DataSource readDruidDataSource() { return new DruidDataSource(); } /** * DataSource 配置 * @return */ @ConfigurationProperties(prefix = "spring.datasource.druid.write") @Bean(name = "writeDruidDataSource") @Primary public DataSource writeDruidDataSource() { return new DruidDataSource(); } }
也許有的人看到這里會(huì)比較疑惑,prefix并沒(méi)有指定配置的全限定名,那它是怎么進(jìn)行配置綁定的呢?
相信大家肯定了解@Value注解,它可以通過(guò)全限定名進(jìn)行配置的綁定,這里的ConfigurationProperties其實(shí)就類似于使用多個(gè)@Value同時(shí)綁定,綁定的對(duì)象就是DataSource類型的對(duì)象,而且是 隱式綁定 的,意味著在配置文件編寫的時(shí)候需要與對(duì)應(yīng)類的字段名稱 相同,比如上述spring.datasource.druid.write.url=jdbc:mysql://localhost:3306/jpa ,當(dāng)然了,你也可以隨便寫個(gè)配置,比如 spring.datasource.druid.write.uuu=www.baidu.com,此時(shí)你只需要在注解中加上以下參數(shù)即可
以上就完成了多個(gè)數(shù)據(jù)源的配置,為讀寫分離做了鋪墊
作用于Class類及其用法
配置文件內(nèi)容
spring.datasource.url=jdbc:mysql://127.0.0.1:8888/test?useUnicode=false&autoReconnect=true&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
java代碼
@ConfigurationProperties(prefix = "spring.datasource") @Component public class DatasourcePro { private String url; private String username; private String password; // 配置文件中是driver-class-name, 轉(zhuǎn)駝峰命名便可以綁定成 private String driverClassName; private String type; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } 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 String getDriverClassName() { return driverClassName; } public void setDriverClassName(String driverClassName) { this.driverClassName = driverClassName; } public String getType() { return type; } public void setType(String type) { this.type = type; } }
用法
@Controller @RequestMapping(value = "/config") public class ConfigurationPropertiesController { @Autowired private DatasourcePro datasourcePro; @RequestMapping("/test") @ResponseBody public Map<String, Object> test(){ Map<String, Object> map = new HashMap<>(); map.put("url", datasourcePro.getUrl()); map.put("userName", datasourcePro.getUsername()); map.put("password", datasourcePro.getPassword()); map.put("className", datasourcePro.getDriverClassName()); map.put("type", datasourcePro.getType()); return map; } }
總結(jié)
@ConfigurationProperties 和 @value 有著相同的功能,但是 @ConfigurationProperties的寫法更為方便
@ConfigurationProperties 的 POJO類的命名比較嚴(yán)格,因?yàn)樗仨毢蚿refix的后綴名要一致, 不然值會(huì)綁定不上, 特殊的后綴名是“driver-class-name”這種帶橫杠的情況,在POJO里面的命名規(guī)則是 下劃線轉(zhuǎn)駝峰 就可以綁定成功,所以就是 “driverClassName”
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://blog.csdn.net/nsplnpbjy/article/details/106359154