SpringBoot 2.X課程學習 | 第六篇:挖掘配置文件的祕密

 

1、兩種配置文件獲取值的方式

        由於廣泛屬性比較簡單,可能複雜屬性有些小夥伴們不知道怎麼獲取。所以我將application.yml和application.properties兩種配置文件中對象複雜屬性定義的內容列舉出來:java

        application.properties文件:web

#自定義list集合
person.lists=a,b,c
#自定義map集合
person.maps.k1=va2
person.maps.k2=v2
#自定義person中的dog對象屬性
person.dog.name=毒瓦斯
person.dog.age=8

       application.yml文件:spring

#自定義map集合
#縮進方式
person:
  maps:
    k1: v2
    k2: v3

#行內方式
person: 
  maps:{k1: v2,k2: v3}


#自定義數組
#縮進方式
person
  lists:
    - 鐮刀灣
    - 瓦斯的

#行內方式
person:
  lists:[鐮刀灣,瓦斯的]

#自定義對象屬性
person:
  dog:
    name: awdwa
    age: 11

     一、方式一  經過@ConfigurationProperties註解     

            @ConfigurationProperties註解做用是告訴springboot將本類中的全部屬性與配置文件中的屬性進行綁定,它須要提供prefix屬性,可經過統一前綴批量將類中屬性和配置文件中屬性進行綁定,使用該方式的時候須要引入配置文件處理器依賴:數組

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

           而且使用添加@Component、@Configuration或者@EnableConfigurationProperties註解,將類做爲容器中的組件,才能使用容器中的功能。 springboot

       示例代碼以下:app

package com.example.demo.entity;

import org.springframework.stereotype.Component;

@Component
@Data
public class Dog {

    private String name;

    private int age;

}

          1.一、使用@Component註解

package com.example.demo.entity;


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Component
@ConfigurationProperties(prefix = "person")
@Data
public class Person {

    private Map<String,Object> maps;

    private List<Object> lists;

    private Dog dog;
}

      1.二、使用@configuration註解:

package com.example.demo.entity;


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@configuration
@ConfigurationProperties(prefix = "person")
@Data
public class Person {

    private Map<String,Object> maps;

    private List<Object> lists;

    private Dog dog;
}

      1.三、使用@EnableConfigurationProperties註解

package com.example.demo.entity;


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@ConfigurationProperties(prefix = "person")
@Data
public class Person {

    private Map<String,Object> maps;

    private List<Object> lists;

    private Dog dog;
}
@SpringBootApplication
@EnableConfigurationProperties(Person.class)
public class DemoApplication {

    @Autowired
    private Person person;

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    @ResponseBody
    public String hello() {
        System.out.println("person" + person);
        return "hello world";
    }

    public static void main(String[] args) {
        //SpringApplication.run(TestProperty1.class, args);
        new SpringApplicationBuilder(DemoApplication.class).web(SERVLET).run(args);

    }
}

二、方式二 經過@Value註解

          @Value註解相似在原始spring項目在配置文件中配置bean標籤,在bean標籤中配置了properties標籤,並提供value屬性值,例如:dom

<bean class="xxx">
  <properties name="xxx" value=""/>
</bean>

@Value註解至關於這個properties標籤中的value屬性值。

         使用@Value註解不能經過前綴批量將類中全部屬性與配置文件中特定屬性綁定,它支持使用${key}(從環境變量、配置文件中獲取值)、#{SpEl}等。函數

         好比:spring-boot

@Value("${person.last-name}")
    private String name;

    @Value("#{11*2}")  /**爲spring表達式
    private int age;

    @Value("true")
    private boolean flag;

      將配置文件中的屬性綁定到類中的屬性時,對於對象屬性,若是鍵包含除小寫字母數字字符或-之外的任何字符,則須要使用括號表示法,以便保留原始值。若是鍵未被[]包圍,則將刪除任何非字母數字或-的字符。好比map屬性:ui

#yml文件寫法
#自定義map集合
person:
  maps:
    "[/key1]": value1
    /key3: value3
    k2: v2


#properties文件寫法
#自定義map集合
person.maps.[/key1]=va2
person.maps./key3=v2

那麼使用註解獲取到的map集合內容爲maps={/key1=va2, key3=v2}

2、@ConfigurationProperties和@Value註解不一樣

  @ConfigurationProperties  @Value
功能 批量注入配置文件中的屬性 只能一個一個的注入
鬆散綁定(Relaxed Binding) 支持 不支持
SrEl表達式 不支持 支持
JSR303數據檢驗 支持 不支持
複雜類型封裝 支持 不支持
綁定類屬性是否提供set、get方法

2.一、鬆散綁定

         好比類中定義了一個屬性,屬性名爲firstName,若是使用@ConfigurationProperties,那麼配置文件中,該屬性能夠寫成以下形式:

person.firstName:使用標準方式
person.first-name:大寫用-,建議在.properties和.yml文件中使用。
person.first_name:大寫用_,它是用於.properties和.yml文件的可選格式。
PERSON.FIRST_NAME  大寫格式,建議在使用系統環境變量時使用。

        可是若是使用@Value註解,那麼只能寫成@Value("${person.firstName}")。

        每一個屬性源的寬鬆綁定規則:

屬性源 Simple List
Properties Files Camel case(駝峯式), kebab case(短橫線), or underscore notation(下劃線符號) 使用[]或逗號分隔值的標準列表語法
YAML Files Camel case(駝峯式), kebab case(短橫線), or underscore notation(下劃線符號) 標準yaml列表語法或逗號分隔值

Environment Variables

(環境變量)

如下劃線做爲分隔符的大寫格式。「-」不該在屬性名中使用 由下劃線包圍的數字值,例如my_Acme_1_Other=my.Acme[1].Other

System properties

(系統屬性)

Camel case(駝峯式), kebab case(短橫線), or underscore notation(下劃線符號) 使用[]或逗號分隔值的標準列表語法

2.二、JSR303數據校驗

        @ConfigurationProperties註解支持JSR303數據校驗,意味着進行數據校驗的屬性必須符合規則纔給予經過,不然報錯。好比給類中的某個屬性添加@Email註解,則規定,該屬性值必須符合郵箱格式才進行經過。查看代碼:

@Validated
public class Person {

    @Value("${person.last-name}")
    @Email
    private String name;

}

2.三、關於綁定類中的屬性是否須要提供set、get方法

   這個狀況只適應於使用@ConfigurationProperties註解。因爲綁定是經過標準javaBean屬性,所以絕大狀況下屬性都須要提供setter和getter方法,除如下狀況能夠省略setter方法:

  • 集合或者數組 能夠經過索引(一般使用yaml)或使用單個逗號分隔值(屬性)訪問。對於數組屬性,setter方法是強制的。咱們建議始終爲此類類型添加setter方法。若是初始化集合,請確保它不是不可變的。
  • 初始化了嵌套的POJO屬性,例如:person類中有一個屬性:private Dog dog=new Dog();則不須要setter方法,可是是private Dog dog;則須要提供setter方法。若是但願綁定器使用其默認構造函數動態建立實例,則須要一個setter方法。
  • 最後,只考慮標準的JavaBean屬性,不支持對靜態屬性的綁定。

3、配置文件佔位符

      springboot配置文件中容許使用隨機數或者在配置文件中引用前面配置過的屬性來做爲佔位符。

      好比使用隨機數的佔位符:

${random.int}
${random.long}
${random.value}
${random.uuid}
${random.int(10)}
${random.int[1024,65523]}

     好比在文件中引用前面配置過的屬性做爲佔位符:

app.name=MyApp
app.decription=${app.name} is a SpringBoot Application

   若是配置文件上下文沒有該屬性時,咱們隨便輸入一個屬性名,那麼它將會把這個屬性名打印出來,好比:

app.name=Myapp
app.decription=${MyProject} is a SpringBoot Application


那麼使用註解獲取app.decription這個屬性值時,打印的結果爲:MyProject is a SpringBoot Application

     咱們還能夠爲這個配置文件上下文都沒有的屬性值賦值。好比以下操做:

app.name=Myapp
app.decription=${MyProject:customProject} is a SpringBoot Application


那麼使用註解獲取app.decription這個屬性值時,打印的結果爲:customProject is a SpringBoot Application

4、配置文件加載順序

相關文章
相關標籤/搜索