SpringBoot 基礎知識學習(二)——配置檔案多環境配置

ldear發表於2017-08-31
通過上一篇《Spring Boot 基礎知識學習(一)——快速入門》我們知道SpringBoot使用預設配置來簡化配置,但是在實際使用時,我們需要更改配置咋辦呢?比如,我們需要把服務啟動埠改成8081?

        SpringBoot的配置檔案有兩種格式,一種是properties,另外一種是yml,由於properties比較簡單,本篇用此格式的配置檔案做舉例(在我們PaaS平臺中是用的yml,後面會有一篇介紹yml的使用)。

二、配置檔案

     spring Boot的預設配置檔案為application.properties或者application.yml。

(1)   修改服務埠

        這個比較簡單,在*.properties檔案中新增“server.port=8081”,可以觀察控制檯檢視服務啟動的埠,具體配置如下所示:


        除了上面這種設定服務啟動埠的方式,我們還可以通過命令列設定值,通過這條命令:Java -jar xxx.jar --server.port=8082,通過使用–server.port屬性來設定xxx.jar應用的埠為8082。那麼問題來了,我同時使用配置檔案和命令列,會怎麼樣呢?會不會程式掛掉或者使用其中的一種呢?這就引出另外一個問題:配置檔案的生效順序或者說他們的優先順序。

(2)   配置的優先順序

         Spring Boot 所提供的配置優先順序順序比較複雜。按照優先順序從高到低的順序,具體的列表如下所示:

A、命令列引數

B、 通過System.getProperties() 獲取的 Java 系統引數

C、 作業系統環境變數

D、 從 java:comp/env 得到的 JNDI 屬性

E、 通過RandomValuePropertySource 生成的“random.*”屬性

F、 應用 Jar 檔案之外的屬性檔案。(通過spring.config.location引數)

G、應用 Jar 檔案內部的屬性檔案

H、 在應用配置 Java 類(包含“@Configuration”註解的 Java 類)中通過“@PropertySource”註解宣告的屬性檔案。

I、  通過“SpringApplication.setDefaultProperties”宣告的預設屬性。

(3)   自定義配置屬性與載入

        我們進行Spring Boot應用程式開發的時候,除了其本身的一些屬性配置外,可能還存在一些自定義的屬性需要配置和讀取,那麼其是怎麼做的,有兩種方式:通過@Value("${屬性名}")註解來載入對應的配置屬性或者使用environment.getProperty()方法根據key獲取value,具體程式碼(原始碼的地址為:https://github.com/dreamerkr/SpringBoot)如下所示:

A、配置檔案application.properties

  1. <span style="font-size:14px;">srd.regProtocol:etcd  
  2. srd.addresses:10.15.15.119:12379</span>  

B、使用@value註解獲取配置屬性的值

  1. @Component  
  2. public class DiscoveryConfig {  
  3.     //型別(zk或者etcd)  
  4.     @Value("${srd.regProtocol}")  
  5.     private String regProtocol;  
  6.      
  7.     //註冊地址  
  8.     @Value("${srd.addresses}")  
  9.     private String address;  
  10.     //省略getter和setter  
  11. }  

C、使用environment.getProperty()方法根據key獲取value

  1. <span style="font-size:14px;">@RestController  
  2. public class HelloController {  
  3.     @Autowired  
  4.     private Environment environment;  
  5.      
  6.     @RequestMapping("/hello")  
  7.     public String sayHello(){  
  8.         return "Hello World "+environment.getProperty("spirng.application.name");  
  9. }  
  10. }</span>  

D、編寫單元測試

  1. @RunWith(SpringJUnit4ClassRunner.class)  
  2. @SpringBootTest(classes={DemoApplication.class})  
  3. public class DemoApplicationTests {s  
  4.     @Autowired  
  5.     private DiscoveryConfig config;  
  6.    
  7.     @Test  
  8.     public void getConfigTest() throwsException {  
  9.          Assert.assertEquals(config.getRegProtocol(), "etcd");  
  10.          Assert.assertEquals(config.getAddress(), "10.15.15.119:12379");  
  11. }  
  12. }  

三、多配置檔案

         我們在使用Spring Boot開發應用或者服務時,通常同一個應用程式或者服務會部署到不同的環境,比如:開發、測試、生產等。其中每個環境的資料庫地址、伺服器埠等等配置都會不同,如果在為不同環境打包時都要頻繁修改配置檔案的話,那必將是個非常繁瑣且容易發生錯誤的事。對於多個環境的配置,各種專案構建工具或是框架的基本思路是一致的,通過配置多份不同環境的配置檔案,再通過打包命令指定需要打包的內容之後進行區分打包,Spring Boot也是通過profile來實現的。

        在Spring Boot中多環境配置檔名需要滿足application-{profile}.properties的格式,其中{profile}對應你的環境標識,比如:application-dev.properties:開發環境,application-test.properties:測試環境等。至於哪個具體的配置檔案會被載入,有三種方式:

(1)    使用@PropertySource註解

         直接在啟動類上使用@PropertySource註解來載入不同的配置檔案,具體如下所示:


(2)    修改spring.profiles.active屬性

         需要在application.properties檔案中通過spring.profiles.active屬性來設定,其值對應{profile}值,如:spring.profiles.active=dev就會載入application-dev.properties配置檔案內容,具體如下所示:


(3)    執行命令列

         如上面介紹所講的一樣,我們可以使用命令列,比如執行java -jar xxx.jar --spring.profiles.active=test,可以觀察到服務埠被設定為8082,也就是測試環境的配置(test)。

總結

         通過上面,三種不同執行方式,我們也可以發現配置檔案的優先順序,優先順序高的配置或覆蓋優先順序低的配置,同時公共配置屬性放到application.properties,私有的配置屬性放在application-{profile}.properties檔案中。

相關文章