SpringBoot中@ConfigurationProperties 配置綁定
SpringBoot底層的一個(gè)功能 : @ConfigurationProperties
@ConfigurationProperties 配置綁定
來(lái)舉一個(gè)場(chǎng)景例子 :
我們習(xí)慣于把經(jīng)常變化的一個(gè)東西配到配置文件里面。比如把數(shù)據(jù)庫(kù)的一些鏈接地址、賬號(hào)、密碼包括數(shù)據(jù)庫(kù)連接池的大小等等這些屬性配到properties配置文件里面,然后為了方便 , 因?yàn)槲覀兾磥?lái)可能要?jiǎng)?chuàng)建數(shù)據(jù)庫(kù)連接池,我們會(huì)把這個(gè)配置文件里面的內(nèi)容又一一解析到我們數(shù)據(jù)庫(kù)連接池(比如javaBean我們這個(gè)對(duì)象里面),所以我們這個(gè)實(shí)現(xiàn)場(chǎng)景就是把properties里面的所有配置綁定JavaBean里面。那我們這個(gè)綁定過(guò)程如果用java原生代碼來(lái)做還是挺麻煩的大概過(guò)程:
public class getProperties { public static void main(String[] args){ Properties pps = new Properties(); pps.load(new FileInputStream("a.properties")); Enumeration enum1 = pps.propertyNames();//得到配置文件的名字 while(enum1.hasMoreElements()){ String strKey = (String) enum1.nextElement(); String strValue = pps.getProperty(strKey); System.out.println(strKey + "=" + strValue); //封裝到JavaBean。 } } }
我們使用Properties這個(gè)類我們加載來(lái)我們這個(gè)配置文件(pps.load(new FileInputStream("a.properties"));)然后遍歷(while(enum1.hasMoreElements()))配置文件的每一個(gè)kv(key-value)值(String strKey = (String) enum1.nextElement(); String strValue = pps.getProperty(strKey););然后把kv值一一對(duì)應(yīng)封裝到JavaBean指定的屬性里
其實(shí)這樣還算簡(jiǎn)單的,復(fù)雜一點(diǎn)的就是:假設(shè)我給你個(gè)你的這個(gè)配置文件(application.properties)這個(gè)文件里面亂七八槽配置了100多行的配置,我讓你在這100多行里面找數(shù)據(jù)與庫(kù)有關(guān)的這四五行,那你可能會(huì)使用到正則表達(dá)式等等一大堆的東西你才能把它解析完成,但在SpringBoot里面,這個(gè)過(guò)程就會(huì)變得非常簡(jiǎn)單,我們把這個(gè)過(guò)程稱為配置綁定;我們只需要一個(gè)注解@ConfigurationProperties
我在這舉了個(gè)例子:
我在這寫了一個(gè)Car.java的類
package com.chentianyu.boot.bean; public class Car { private String brand; private Integer price; public String getBrand(){return brand;} public void setBrand(String brand){this.brand = brand;} public Integer getPrice(){return price;} public void setPrice(Integer price){this.price = price;} @Override public String toString(){ return "Car{" + "brand = " + brand + '\'' + ", price = " + price + "}"; } }
我們可以看做是JavaBean Car
Car有倆個(gè)屬性:一個(gè)是brand(品牌),另一個(gè)是price(價(jià)格)
我現(xiàn)在想把跟Car有關(guān)的屬性放到配置里面,我們就放springboot的application.properties這個(gè)配置文件里面。配置文件我隨便寫:比如我們直接寫個(gè)mycar
application.properties
mycar.brand=BYD #我的汽車的這個(gè)品牌,比如BYD(比亞迪) mycar.price=100000 #我汽車的這個(gè)價(jià)格
現(xiàn)在我配了汽車的倆個(gè)信息;那如果是我們以前我們要讀取這個(gè)配置文件我們要在Car.java里面封裝很麻煩現(xiàn)在怎么做(一個(gè)注解,叫@ConfigurationProperties):
@ConfigurationProperties public class Car{...}
ConfigurationProperties.java
package org.springframework.boot.context.properties; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.core.annotation.AliasFor; import org.springframework.stereotype.Indexed; @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented @Indexed public @interface ConfigurationProperties { @AliasFor("prefix") String value() default ""; @AliasFor("value") String prefix() default ""; boolean ignoreInvalidFields() default false; boolean ignoreUnknownFields() default true; }
這個(gè)里面有我們要寫的東西叫prefix(@AliasFor("prefix")),這個(gè)prefix跟這個(gè)value()其實(shí)都是互相都是別名(@AliasFor)
@ConfigurationProperties(prefix = "mycar") public class Car{...}
這個(gè)prefix指的是這個(gè)前綴,這個(gè)前綴的意思就是我們這個(gè)Car類里面的每一個(gè)屬性跟配置文件哪個(gè)前綴下的屬性一 一綁定。我們配置文件里面正好有mycar它的這個(gè)品牌名(brand)還有我們這個(gè)價(jià)格(price)跟我們JavaBean里面的品牌(brand)和價(jià)格(price)一模一樣所以我就把mycar寫上。
寫上以后我們?yōu)榱俗屗В覀儼堰@個(gè)組件**加到容器(@Component)**中 , 因?yàn)槲覀內(nèi)萜髦械慕M件才能擁有我們SpingBoot給它提供的強(qiáng)大功能(也就是容器提供的強(qiáng)大功能)
我們來(lái)測(cè)試一下:
我們Car組件(Car.java)它里的這些值是不是默認(rèn)已經(jīng)跟application.properties配置文件里面的mycar它下面的值一 一綁定上了?(寫一個(gè)Controller進(jìn)行測(cè)試)
HelloController.java
public Car car(){ return }
這個(gè)car從哪來(lái)? 因?yàn)槲覀冇聾Component放在容器中了,而且它這個(gè)容器中實(shí)例的每一個(gè)屬性的值都跟配置文件中綁定的,所以我想要用的話,直接利用Spring的自動(dòng)注入(@Autowired)把容器中的Car拿過(guò)來(lái)就行了
@Autowired Car car; @RequestMapping("/car")//處理一個(gè)請(qǐng)求 public Car car(){ return car;//我們返回這Car }
打開(kāi)瀏覽器輸入localhost:8080/car,得到的結(jié)果為:
{"brand":"BYD","price":100000}
包括我們配置文件改了:
mycar.brand=YD #我的汽車的這個(gè)品牌,比如BYD(比亞迪) mycar.price=100000 #我汽車的這個(gè)價(jià)格
注意:配置文件改了我們程序一定要重新啟動(dòng)
然后重新測(cè)試:
{"brand":"YD","price":100000}
所以現(xiàn)在想要讓一個(gè)JavaBean與配置文件里面的東西一 一綁定,我們第一種辦法就是@ConfigurationProperties注解 , 我們?nèi)萜髦械慕M件,標(biāo)注@ConfigurationProperties注解。
這個(gè)方式叫@Component + @ConfigurationProperties
第二個(gè)辦法,還有一種寫的方式
第二個(gè)方式就是:
@EnableConfigurationProperties + @ConfigurationProperties
比如我們?cè)谂渲妙?MyConfig)里面(第二種方式一定要在配置類里面寫,因?yàn)榕渲妙愂紫仁侨萜髦械慕M件(@Configuration))然后我們?cè)谂渲妙惿蠈懯裁床拍苌??寫一個(gè)@EnableConfigurationProperties意思就是開(kāi)啟我們這個(gè)屬性配置功能,開(kāi)啟誰(shuí)的屬性配置功能?我們這個(gè)Car想要跟人綁定所以我們把Car
傳進(jìn)@EnableConfigurationProperties()里面來(lái):
@Configuration(proxyBeanMethods = false)//告訴SpringBoot這是一個(gè)配置類(把這個(gè)類說(shuō)明@Configuration類似于告訴spring這個(gè)文件是配置文件)
@ConditionalOnMissingBean(name = "tom") @ImportResource("classpath:beans.xml") @EnableConfigurationProperties(Car.class) public class MyConfig {...}
那我們這個(gè)@EnableConfigurationProperties就有倆個(gè)功能:
1、開(kāi)啟Car的配置綁定(屬性配置)功能
- 你只有開(kāi)啟了Car的屬性配置功能也就是Car.java下面的屬性配置才能生效想要開(kāi)啟屬性配置功能第一個(gè)你明顯的標(biāo)注@EnableConfigurationProperties()開(kāi)啟誰(shuí)的屬性配置功能(這里只Car)。
- 第二種辦法就是你只要這個(gè)組件在容器(@Component)中 , 它默認(rèn)我們提供的這些功能他就能生效
2、把這個(gè)組件自動(dòng)注冊(cè)到容器中(這里指Car這個(gè)組件)
- 相當(dāng)于我們就不用再寫@Component了。因?yàn)橛行r(shí)候可能是這樣子的:我們的這個(gè)Car有可能是引用的是第三方包里面的,第三方包里面的人家類里面有可能沒(méi)標(biāo)@Component,你是不是也不可能往人家寫的類上標(biāo)@Component, 那咋辦呢?我就可以用@EnableConfigurationProperties()把人家的第三方包一整過(guò)來(lái)。@EnableConfigurationProperties的倆個(gè)功能(1)開(kāi)啟了你的配置綁定(2)把你這個(gè)使用別人第三方包的組件自動(dòng)注冊(cè)到了容器中,我們還能測(cè)試生效
我們不用@EnableConfigurationProperties我們只說(shuō)Car是屬性綁定(@ConfigurationProperties)而且沒(méi)把它加在容器(@Component)中。
***************************
APPLICATION FAILED TO START
***************************Description:
Field car in com.chentianyu.boot.controller.HelloController required a bean of type 'com.chentianyu.boot.bean.Car' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)Action:
Consider defining a bean of type 'com.chentianyu.boot.bean.Car' in your configuration.
Process finished with exit code 1
我們啟動(dòng)都報(bào)錯(cuò)了,報(bào)錯(cuò)的原因就是HelloController.java里面有用Car這個(gè)Car在容器中沒(méi)有,所以拿不到,自動(dòng)裝配(@Autowired)失敗,所以我們這一塊報(bào)錯(cuò)了。
倆種辦法
- 你要么就把它(@ConfigurationProperties)加在容器(@Component)中
- 要么就使用這種開(kāi)啟功能的方式(@EnableConfigurationProperties)
這倆種都行,這是我們說(shuō)的配置綁定,有了這個(gè)配置綁定那我們后來(lái)其實(shí)哪怕自定義的一些配置(比如 mycar.brand和mycar.price)你想綁給哪個(gè)JavaBean就綁給哪個(gè)JavaBean , 只是一個(gè)@ConfigurationProperties注解的問(wèn)題,我們不用再寫以前一堆的代碼,而且ConfigurationProperties我們?cè)谖磥?lái)SpringBoot底層大家經(jīng)常見(jiàn)到,你見(jiàn)到這個(gè)東西@ConfigurationProperties就說(shuō)明這個(gè)類(Car)中的所有屬性是跟SpringBoot核心配置文件(application.properties),你也不能隨便寫一個(gè)別的文件 它綁定不上,是跟我們application.properties這個(gè)核心文件里面prefix = "mycar"這個(gè)前綴下邊的所有東西進(jìn)行綁定的
到此這篇關(guān)于SpringBoot中@ConfigurationProperties 配置綁定的文章就介紹到這了,更多相關(guān)@ConfigurationProperties 配置綁定內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot整合持久層的方法實(shí)現(xiàn)
本文主要介紹了springboot整合持久層的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09idea項(xiàng)目debug模式啟動(dòng),斷點(diǎn)失效,斷點(diǎn)紅點(diǎn)內(nèi)無(wú)對(duì)勾問(wèn)題及解決
這篇文章主要介紹了idea項(xiàng)目debug模式啟動(dòng),斷點(diǎn)失效,斷點(diǎn)紅點(diǎn)內(nèi)無(wú)對(duì)勾問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10java執(zhí)行SQL語(yǔ)句實(shí)現(xiàn)查詢的通用方法詳解
這篇文章主要介紹了java執(zhí)行SQL語(yǔ)句實(shí)現(xiàn)查詢的通用方法詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-12-12淺談JAVA實(shí)現(xiàn)選擇排序,插入排序,冒泡排序,以及兩個(gè)有序數(shù)組的合并
這篇文章主要介紹了JAVA實(shí)現(xiàn)選擇排序,插入排序,冒泡排序,以及兩個(gè)有序數(shù)組的合并,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03java:無(wú)法訪問(wèn)org.springframework.boot.SpringApplication的解決方法
這篇文章主要給大家介紹了關(guān)于java:無(wú)法訪問(wèn)org.springframework.boot.SpringApplication的解決方法,文中通過(guò)實(shí)例代碼將解決的辦法介紹的非常詳細(xì),需要的朋友可以參考下2023-01-01