微服務 SpringBoot 2.0(二):配置文件解析

properties我用了好多年,你卻讓我用yml,這是什麼鬼 —— Java面試必修css

引言

上一篇介紹了Spring Boot的輕鬆入門項目構建,對Spring Boot的特性有了初步瞭解。但若是要想玩得很熟練的話就請看接下來的文章,這樣有助於後續咱們快速的構建企業級應用,打怪咱得先熟悉地圖對吧java

配置詳解

工具

  • SpringBoot版本:2.0.4
  • 開發工具:IDEA 2018
  • Maven:3.3 9
  • JDK:1.8

配置文件類型

本文主要講解SpringBoot的配置文件,經常使用的配置文件類型有以下兩種,分爲properties、yml,先甭管什麼文件,SpringBoot都能正確加載讀取裏面的參數,配置文件的路徑在:src/main/resources面試

  1. properties結尾的文件,這種想必你們都比較熟悉了,好比:jdbc.properties,或log4j.properties
  2. yml結尾的文件,YAML(Yet Another Markup Language)結構化的數據配置文件,諧音(亞妹襖),ML和XML同音

動手嘗試

  1. 2種配置都可讀取的固定代碼,配置請往下看
@RestController
@SpringBootApplication
public class DemoApplication {

    @Value("${com.demo.name}")
    private String name;

    @Value("${com.demo.url}")
    private String url;

    @RequestMapping("/index")
    public String index(){
        return "name:" + name +",url:" + url ;
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);

    }
}

 

  1. application.properties,先來個簡單的配置,代碼@Value註解直接綁定
com.demo.name="JAVA面試必修" com.demo.url="www.itmsbx.com" 
結果:成功返回name:「Java面試必修」,url:"www.itmsbx.com" 

  1. 換成 application.yml 則內容以下
#註釋
com.demo.name: Java面試必修 com.demo.url: www.itmsbx.com ---- yml上下任選一種便可 com.demo: name: Java面試必修 url: www.itmsbx.com 
結果:name:Java面試必修,url:www.itmsbx.com 

Spring框架提供兩個便利的類用於加載YAML文檔,YamlPropertiesFactoryBean會將YAML加載爲PropertiesYamlMapFactoryBean會將YAML加載爲Map,後續講解spring

Bean對象綁定

認識了配置文件後,咱們發現yml中的數據綁定還挺好用的。可是問題來了,一個個綁定到屬性字段上太累,能換成對象,我們就使用對象對吧,那也是能夠的,咱們建一個DemoBean.java類。數據庫

  1. Bean類中使用註解 @ConfigurationProperties(prefix = 「com.demo」)來指明綁定配置文件中哪一個變量
@ConfigurationProperties(prefix = "com.demo")
public class DemoBean {

    //省略getter和setter
    private String name;
    private String url;

}

 

  1. Controller中使用註解@EnableConfigurationProperties({DemoBean.class})來綁定實體類,並使用Autowired在成員變量處注入便可
@RestController
@SpringBootApplication
@EnableConfigurationProperties({DemoBean.class})
public class DemoApplication {

    @Autowired
    DemoBean demoBean;


    @RequestMapping("/index")
    public String index(){
        return "name:" + demoBean.getName() + ",url:" + demoBean.getUrl();
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);

    }
}

 

結果:name:Java面試必修,url:www.itmsbx.com 

參數與參數間的引用

# 註釋 com.demo: name: Java面試必修 url: www.itmsbx.com scope: ${com.demo.name}的網址是${com.demo.url} 

這樣咱們直接使用scope屬性就能看到效果了,注:properties和yml除了書寫格式上的差別外,使用方式基本相似,因此後續咱們的講解中都建議使用yml文件json

隨機參數生成

一般是用這些隨機數咱們得寫一段代碼生成,如今配置文件中${random} 能夠用來生成各類不一樣類型的隨機值,從而簡化了代碼生成的麻煩,例如 生成 int 值、long 值或者 string 字符串tomcat

demo.secret: ${random.value}
demo.number: ${random.int}
demo.bignumber: ${random.long}
demo.uuid: ${random.uuid}
demo.number.less.than.ten: ${random.int(10)}
demo.number.in.range: ${random.int[1024,65536]}

 

你們仔細思考下,${}很熟悉,咱們用本身的變量也是${}包含起來的對不對,那其實這是SpringBoot已經封裝好的配置變量啦,相似於jsp中的隱式對象request同樣,拿來即用ruby

命令行參數配置

Spring Boot是基於jar包運行的,打成jar包的程序能夠直接經過下面命令運行:bash

java -jar demo-0.0.1-SNAPSHOT.jar 

可使用下命令修改tomcat端口號:mvc

java -jar demo-0.0.1-SNAPSHOT.jar --server.port=9090

等價於在yml中配置server.port: 9090,或properties中配置server.port=9090
java -jar demo-0.0.1-SNAPSHOT.jar

控制檯輸出

$ java -jar myapp.jar --debug
但前提是你須要在yml或properties中指明 debug=true 

設置Spring profiles參數啓動

$ java -jar -Dspring.profiles.active=production demo-0.0.1-SNAPSHOT.jar 

命令啓動參數用 --xxx=xxx 的形式傳遞。命令行參數在demo.jar的後面,若是你擔憂命令行有風險,則可使用SpringApplication.setAddCommandLineProperties(false)禁用它。

運行或系統參數獲取

Spring Boot應用程序有多種設置途徑,Spring Boot能從多重屬性源得到屬性,包括以下幾種(優先級從高到低排序):

  • 命令行參數
  • SPRING_APPLICATION_JSON中的屬性(環境變量或系統屬性中的內聯JSON嵌入)。
  • ServletConfig初始化參數。
  • ServletContext初始化參數。
  • 來自java:comp/env的JNDI屬性
  • Java系統屬性(System.getProperties()
  • 操做系統環境變量
  • RandomValuePropertySource配置的random.*屬性值,好比${random.long}
  • jar包外部的application-{profile}.propertiesapplication.yml(帶spring.profile)配置文件
  • jar包內部的application-{profile}.propertiesapplication.yml(帶spring.profile)配置文件
  • jar包外部的application.propertiesapplication.yml(不帶spring.profile)配置文件
  • jar包內部的application.propertiesapplication.yml(不帶spring.profile)配置文件
  • @Configuration註解類上的@PropertySource
  • 經過SpringApplication.setDefaultProperties指定的默認屬性

任何在高優先級屬性源裏設置的屬性都會覆蓋低優先級的相同屬性,列如咱們上面提到的命令行屬性就覆蓋了application.properties的屬性。

配置文件的優先級

application.propertiesapplication.yml文件能夠放在如下四個位置:

  • 外置,在相對於應用程序運行目錄的/congfig子目錄裏。
  • 外置,在應用程序運行的目錄裏
  • 內置,在config包內
  • 內置,在Classpath根目錄

一樣,這個列表按照優先級排序,也就是說,src/main/resources/config/application.properties覆蓋src/main/resources/application.properties中相同的屬性,如圖:

 
配置文件優先級

 

此外,若是你在相同優先級位置同時有application.propertiesapplication.yml,那麼application.properties裏的屬性裏面的屬性就會覆蓋application.yml

使用自定義的配置文件

對於同時加載多個properties配置文件,SpringBoot有註解@PropertySource支持,而yml多配置文件須要單獨用程序讀取,官方提供了YamlPropertySourceLoader.java類來支持,因此@PropertySource只能支持properties配置文件,以下:

@Configuration
@ConfigurationProperties(prefix = "com.custom")
@PropertySource("classpath:application-test.properties")
public class CustomBean {

    //省略getter和setter
    private String sex;
    private String age;
    private String desc;
    
}

 

若對於yml多配置文件,建議寫到一個裏面,但若是分紅多個環境加載不一樣配置,那接下來咱們就講解下如何經過命令參數調用不一樣的yml

Profile-多環境配置

普通springmvc項目解決方案

在普通的springmvc的tomcat項目中,咱們也能夠指定JVM的運行參數,在啓動服務的時候經過System.getProperty("JVM配置key")獲取到這個參數,而後初始化不一樣的Properties文件,操做以下:

 

 
普通springmvc項目,properties文件
 <!-- 從properties文件加載配置信息 -->
    <bean id="propertyPlaceholderConfigurer" class="com.xx.xx.common.spring.CustomizedPropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <!-- 此處配置文件須要在tomcat運行參數中指定[develop|test|product]其中一個,若不指定,默認取develop -->
                <value>classpath*:**/config/config-develop.properties</value>
                <value>classpath*:**/config/config-test.properties</value>
                <value>classpath*:**/config/config-product.properties</value>
            </list>
        </property>
        <property name="configureClasses">
            <list>
                <value>com.xx.xx.common.util.Constants</value>
            </list>
        </property>
    </bean>

    tomcat 中 catalina.bat(.sh中不用「set」) 添加JAVA_OPS。經過設置active選擇不一樣配置文件
    set JAVA_OPTS="-Dspring.profiles.active=test"

 

上述的CustomizedPropertyPlaceholderConfigurer類實現了PropertyPlaceholderConfigurer,在初始化的時候經過獲取JVM的profile進行不一樣的properties選取

SpringBoot解決方案

對於多環境的配置,各類項目構建工具或是框架的基本思路是一致的,經過配置多份不一樣環境的配置文件,再經過打包命令指定須要打包的內容以後進行區分打包,Spring Boot也不例外,或者說更加簡單。

在Spring Boot中多環境配置文件名須要知足application-{profile}.yml的格式,其中{profile}對應你的環境標識,以下圖:

 
yml結構

至於哪一個具體的配置文件會被加載,須要在application.yml文件中經過spring.profiles.active屬性來設置,其值對應{profile}值。如:spring.profiles.active=prod就會加載application-prod.yml配置文件內容

application.yml內容以下

spring.profiles.active: dev 

application-dev.yml內容以下

server:
  port: 1000

application-prod.yml內容以下

server:
  port: 1001

啓動的時候帶上參數:java -jar xxx.jar --spring.profiles.active=dev,就會發現啓動的端口不同,說明配置文件生效了


代碼使用profile

除了能夠用profile的配置文件來分區配置咱們的環境變量,在代碼裏,咱們還能夠直接用@Profile註解來進行配置,例如數據庫配置,這裏咱們先定義一個接口

public interface DBConnector { public void dbConfig(); } 

分別定義倆個實現類來實現它

/**
  * 開發數據庫
  */
@Component
@Profile("devdb")
public class DevDBConnector implements DBConnector {
    @Override
    public void dbConfig() {
        System.out.println("devdb");
    }
}
/**
 * 生產數據庫
 */
@Component
@Profile("prodb")
public class ProDBConnector implements DBConnector {
    @Override
    public void dbConfig() {
        System.out.println("prodb");
    }
}

 

經過在配置文件激活具體使用哪一個實現類

spring.profiles.active=prodb

而後具體調用以下

@RestController
@RequestMapping("/call")
public class CallController {

    @Autowired DBConnector connector ;

    @RequestMapping(value = {"/",""})
    public String hellYml(){

        connector.dbConfig(); //最終打印prodb
        return "Hello yml";
    }
}

 

總結

SpringBoot的配置文件給咱們帶來了極大的便利,properties和yml二者各選一個吧,不過我更傾向於yml,其格式化的配置看起來很舒服,有點相似於json格式,更多的屬性及配置後續在使用的過程當中慢慢講解。


做者有話說:喜歡的話就請移步Java面試必修網,請自備水,更多幹、幹、乾貨等着你

相關文章
相關標籤/搜索