1. 程式人生 > >SpringBoot獲取配置檔案,就這麼簡單。

SpringBoot獲取配置檔案,就這麼簡單。

![](https://cdn.jsdelivr.net/gh/zhangfu1111/Blogimagemanager/images/20200530224659.png) 在講SpringBoot 獲取配置檔案之前我們需要對SpringBoot 的專案有一個整體的瞭解,如何建立SpringBoot 專案,專案結構等等知識點,我在這裡就不一一講述了,沒有學過的小夥伴可以自己在網上找一些資料進行學習,很簡單的。 下面讓我們開始今天的內容講解吧。 ## 一、SpringBoot 全域性配置檔案的載入順序 在SpringBoot 當中,全域性配置檔案有兩種不同的格式,一個是我們常見的properties, 一種是yml. 這兩種格式的檔案其實也沒什麼太大的區別,使用的時候按照個人的習慣來就行,下面我們用的是yml檔案。 首先,當我們建立SpringBoot 的專案時,預設在resources目錄下建立一個application.properties檔案,這時我們可以在這個檔案當中對專案進行配置即可。但是在SpringBoot 中application.properties可以存放在以下幾個位置: > file:./config/ 專案根目錄下的config資料夾下 > file:./ 專案根目錄下 > classpath:/config/ 類路徑下的config資料夾下 > classpath:/ 類路徑下 檔案的載入順序:即根目錄下的config目錄下,然後是 根目錄下,然後是classpath路徑下的config目錄下,最後是classpath路徑下。 ![](https://cdn.jsdelivr.net/gh/zhangfu1111/Blogimagemanager/images/20200530201806.png) 優先順序由高到低,高優先順序的配置會覆蓋低優先順序的配置。 假如:根目錄下的config目錄下定義埠為8084, 根目錄下定義埠為8083 ,classpath路徑下的config目錄定義埠為8082,classpath路徑下定義埠為8081,最後啟動,啟動的埠為8084 ,高優先順序會覆蓋低優先順序。 注意: 並不是高優先順序的被載入了,低優先順序的就不會再載入,實際上是SpringBoot會從這四個位置全部載入主配置檔案,並且還能產生互相配置的效果。 除此外,我們還可以通過spring.config.location來改變預設的配置檔案位置。 專案打包好以後,我們可以使用命令列引數的形式,啟動專案的時候來指定配置檔案的新位置;指定預設載入的這些配置檔案共同起作用形成互補配置。 在 G盤目錄下,建立一個application.yml
檔案,定義埠為8085 打包專案,啟動命令列:java -jar spring-boot-config-0.0.1-SNAPSHOT.jar --spring.config.location=G:/application.yml 回車執行。 ***外部配置載入順序*** 1. 命令列引數 eg: java -jar spring-boot-config-0.0.1-SNAPSHOT.jar --server.port=8087 ---- 由jar包外向jar包內進行尋找: ​ 2、 優先載入帶profile jar包外部的 application-{profile}.properties
或application.yml(帶spring.profile)配置檔案 將打好的jar包放在一個目錄下,然後再該資料夾下新建一個名為application.yml的檔案,其中指定 port為8082 ,訪問路徑為/boot ,然後命令列直接啟動專案。java -jar spring-boot-config-0.0.1-SNAPSHOT.jar --application.yml ## ![](https://cdn.jsdelivr.net/gh/zhangfu1111/Blogimagemanager/images/20200530204059.png) **在講配置檔案之前,我先說一說yml檔案配置資訊書寫格式** 基本資料型別(8種基本資料型別)以k: v 形式書寫即可 比如我在一個實體類(Person)中定義一個 屬性(age),型別是 int ,在yml檔案中的書寫格式如下 ``` person: age: 20 ``` 實體類物件(Person),Map ,k:v 在下一行來寫物件的屬性和值的關係,注意縮排 ``` person: userName: zhans age: 20 ``` ``` #另一種行內寫法 person: {userName: zhans.age: 20} ``` List ,陣列的書寫,注意 - 後有空格 ``` pets: - cat - dog - pig ``` ``` #另一種行內寫法 pets:{cat,dog,pi} ``` ## 二、SpringBoot 獲取配置檔案的方式 **@Value ** 建立配置類,由於篇幅問題這裡省略了 setter、getter 方法,但是實際開發中這個是必須的,否則無法成功注入,@Component表示把當前配置類注入到Spring容器當中。 ```text @Component public class PersonConfig { @Value("${person.userName}") private String userName; @Value("${person.age}") private int age; } ``` 在主配置檔案中新增如下配置(application.yml) ``` server: port: 8081 person: userName: hello age: 20 ``` 測試類: ``` @RestController public class PersonController { @Autowired private Person person; @RequestMapping(value = "/get",method = RequestMethod.GET) public String findPerson(){ return "姓名:"+person.getUserName()+"年齡:"+person.getAge(); } } ``` 啟動專案,訪問地址http://localhost:8080/get
執行結果: ``` 姓名:hello年齡:20 ``` > 所以,我們就可以通過 `@Value(${key})`的方式獲取全域性配置檔案中的指定配置項。 **@ConfigurationProperties** 如果我們需要取 許多個配置項,通過 @Value 的方式去配置項需要一個一個去取,顯然有點麻煩。所以我們可以使用 `@ConfigurationProperties`。 > 標有 `@ConfigurationProperties`的類的所有屬性和配置檔案中相關的配置項進行繫結,繫結之後我們就可以通過這個類去訪問全域性配置檔案中的屬性值。 程式碼例項如下: 1. 在主配置檔案中新增如下配置 ```text user: username: admin password: 123456 map: {k1: v1,k2: v2} list: - cat - dog person: userName: hello age: 20 objects: - aaa - bbb - ccc ``` 1. 建立配置類,由於篇幅問題這裡省略了 setter、getter ,toString 方法,但是實際開發中這個是必須的,否則無法成功注入。 ```text @Component @ConfigurationProperties(prefix = "user") public class User { private String username; private String password; private Map map; private Person person; private List list; private Object[] objects; } ``` > 這裡 @ConfigurationProperties 有一個 `prefix`引數,主要是用來指定該配置項在配置檔案中的字首,即user。 測試類 ``` @RestController public class PersonController { @Autowired private Person person; @RequestMapping(value = "/findUser",method = RequestMethod.GET) public String findUser(){ return user.toString(); } } ``` 我們在頁面訪問 http://localhost:8081/findUser,頁面就顯示我們在yml檔案中配置的資訊了。 ``` User{username='admin', password='123456', map={k1=v1, k2=v2}, person=com.zfcoding.config.Person@93471e6, list=[cat, dog], objects=[aaa, bbb, ccc]} ``` 以上的兩種方式有什麼區別呢? | | @ConfigurationProperties | @Value | | -------------- | ------------------------ | ------------- | | 功能 | 批量注入配置檔案的屬性 | 一個一個指定 | | 鬆散繫結 | 支援 | 不支援 | | JSR303資料校驗 | 支援 | 不支援 | | 複雜資料封裝 | 支援 | 不支援(Map) | 鬆散繫結,username 可以用user-name 表示,來獲取值 JSR303資料校驗,如果用@Value獲取全域性配置檔案的屬性,使用@Validated檔案格式校驗是不起作用的。 **@PropertySource 註解載入指定的配置檔案。** ​ @PropertySource (value = “ ”) 指明載入類路徑下的哪個配置檔案來注入值 建立配置類,由於篇幅問題這裡省略了 setter、getter ,toString 方法,但是實際開發中這個是必須的,否則無法成功注入。 ``` @Component @PropertySource( "classpath:student.properties") @ConfigurationProperties(prefix = "student") public class Student { private String sname; } ``` 在student.properties檔案中新增如下配置 ``` student.sname=admin ``` 測試類 ``` @SpringBootTest class SpringbootExampleApplicationTests { @Autowired private DogConfig dogConfig; @Test void contextLoads() { System.out.println("注入的物件:"+dogConfig.getName()); } } ``` 執行結果: ``` Student{sname='admin'} ``` **@ImportResource 匯入Spring 配置檔案** > @ImportResource 註解用來匯入 Spring 的配置檔案,如果Spring配置檔案 "bean.xml",從而讓配置檔案裡面的內容生效,通常可以把@ImportResource標註在@SpringBootApplication的啟動類上即可。 舉例說明:比如我們把PersonService注入到Spring容器當中,通過Spring配置檔案的方式操作,程式碼示例如下: ``` public class PersonService { } ``` ``` @ImportResource("classpath:bean.xml") @SpringBootApplication public class SpringBootConfigApplication { public static void main(String[] args) { SpringApplication.run(SpringBootConfigApplication.class, args); } } ``` Spring的配置檔案:bean.xml ``` ``` 測試的案例: ``` @SpringBootTest class SpringBootConfigApplicationTests { @Autowired private PersonService personSerivcer; @Test void contextLoads() { System.out.println("注入的物件:"+personSerivcer); } } ``` 執行的結果: ``` 注入的物件:com.zfcoding.service.PersonService@5b84f14 ``` 這Spring 中bean的配置實現,但是SpringBoot 推薦我們使用註解開發,那Springboot 中註解是如何實現bean 的注入呢? @Configuration:指明當前類是配置類,就是代替上面說到的spring的配置檔案. @Bean 將方法返回值新增到容器當中,容器中這個元件預設的id 是方法名 ``` @Configuration public class MyConfig { @Bean public PersonSerivcer personSerivcer(){ return new PersonSerivcer(); } } ``` 這樣就可以就可以通過註解實現代替Spring 中的配置檔案了。 ## 三、SpringBoot 的Profile 我們這裡就以yml檔案為例 第一種是我在 主配置檔案編寫的時候,檔名可以是 application-{profile}.yml(application-dev.yml, application-prod.yml) ,預設使用 檔案application.yml 的配置 **1、如果我們想要使用的application-dev.yml 全域性配置檔案,在application.yml 指定即可。** 配置例項: 在application.yml 配置檔案中新增如下配置 ``` spring: profiles: active: dev ``` 在application-dev.ym 配置檔案中新增如下配置l ``` server: port: 8080 #應用訪問的專案路徑 servlet: context-path: /boot person: username: 佔山 ``` **2、yml支援多文件快方式** 那麼,在application-dev.ym 配置檔案中新增如下配置l ``` spring: profiles: active: prod --- server: port: 8080 servlet: context-path: /zf spring: profiles: dev --- person: userName: 啊哈 server: port: 8081 servlet: context-path: /boot spring: profiles: prod ``` **3、Program arguments**    在Program arguments中配置引數 >--spring.profiles.active=dev ![image-20200524174511729](https://img2020.cnblogs.com/blog/1676710/202005/1676710-20200531085248677-1915892015.png) **4、虛擬機器的方式** > 在VM options下使用命令:-Dspring.profiles.active=prod ![image-20200524174645120](https://img2020.cnblogs.com/blog/1676710/202005/1676710-20200531085249267-323570891.png) ## 四、小結 實際開發中我們如果如果我們需要取 許多個配置項,就使用@ConfigurationProperties註解,如果只是注入一個屬性就使用@Value, @PropertySource 註解載入指定的配置檔案,@ImportResource 匯入Spring 配置檔案(這裡可以使用註解來替代)。 ## 後記 由於本人能力有限,若文章有錯誤的地方,請大家指出,一起交流學習。今天就和大家講到這裡,喜歡我的小夥伴們,動動你的小手點個關注唄。 歡迎大家關注我的公眾號:阿福聊程式設計,長期更新Java各種技術文章。 ![](https://cdn.jsdelivr.net/gh/zhangfu1111/Blogimagemanager/images/20200530224