[02] SpringBoot的項目屬性配置


一、application.properties 簡述

配置文件的使用和調整都很是方便,直接在項目默認的classpath下的application.properties文件中作調整便可。例如SpringBoot中默認的Tomcat毒啓動端口是8080,咱們須要調整爲8081,那麼直接在配置文件中調整server.port屬性便可:

默認的application配置文件是 .properties 格式,實際上你還可使用 YAML 格式,即 .yml,如上圖中的配置用 YAML 格式寫則是:

YAML 格式的配置文件,以縮進來表示屬性之間的層級關係,從上面兩種的對比咱們已經能看出,YAML 格式的配置文件結構更加簡潔清晰。固然,若是使用 YAML 格式的配置文件的話,還須要額外學習一下它的語法( 阮一峯:YAML 語言教程),主要是結構表示,特別在書寫時還應注意 縮進/空格 的使用,保證語法的正確性。

二、配置文件的加載順序

(官方說明: 24.3 Application Property Files
SpringBoot應用會從以下四個位置加載application.properties文件,讀取並載入到應用環境中去:
  • 當前目錄下的 /config 目錄
  • 當前目錄
  • classpath下的 /config 目錄
  • classpath 根目錄

注意: 如上的順序是按照優先級排列的(從高到低),這意味着哪怕是同一個key的配置分別在不一樣位置的文件中,會優先選擇 "當前目錄下的 /config 目錄"下的配置文件的值,也就是說,若是在優先級更高的位置找到了配置,則會無視優先級低的配置。 這一樣也意味着若是你想在測試/生產環境中快速修改配置參數,只須要在jar包以外的配置文件進行修改便可,不須要從新打包和部署應用。

這裏的當前目錄,是指與SpringBoot項目jar包同級的目錄,如某個項目打包後的jar包在文件夾 /demo/springboot-demo.jar,則對應如上爲:
  •  /demo/config/application.properties 
  •  /demo/application.properties
  •  /demo/springboot-demo.jar/BOOT-INF/classes/config/application.properties
  •  /demo/springboot-demo.jar/BOOT-INF/classes/application.properties

固然,實際上展開來講SpringBoot讀取配置的優先級不止上面的這幾種,好比說優先級最高的其實是命令行參數,即你在啓動 jar 時經過命令行傳入的配置參數。

三、自定義屬性與加載

在類中,咱們能夠經過註解 @Value("${屬性名}") 的方式將配置文件中的值注入到類中,以下配置文件有值:
server:
  port: 8081

person:
  name: zhangsan
  age: 18

接着咱們可使用註解 @Value("${person.xxx}") 來將配置文件的值讀入:
@Component
public class Person {
    @Value("${person.name}")
    private String name;
    @Value("${person.age}")
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

寫個Controller看看吧:

四、@ConfigurationProperties

自定義屬性與加載中提到的 @Value 方法,在配置較多時仍然顯得有些繁重,SpringBoot提供了更簡潔的方式,即 @ConfigurationProperties,該註解還有一個屬性 prefix,能夠指定配置文件的前綴,而且對類按屬性名進行自動匹配。如上例中的 Person,換用 @ConfigurationProperties 的話,則以下:
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

注意添加依賴:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

五、參數間的引用

在 application.properties 文件中,各個參數也能夠相互引用,仍然是經過 ${屬性名} 的方式,以下 zhangsan.name 就會引用 person.name 的值,age同理:
server:
  port: 8081

person:
  name: zhangsan
  age: 18
  
zhangsan:
  name: ${person.name}
  age: ${person.age}

六、使用隨機值

在某些狀況下,咱們但願某些配置不是一個固定的值,那麼能夠在配置文件中使用 ${random.xx} 來產生int、long、String等隨機值。如:
# 隨機字符串
person.value=${random.value}
person.name=${random.string}

# uuid
person.name=${random.uuid}

# 隨機int
person.age=${random.int}

# 隨機long
person.height=${random.long}

# 10之內的隨機數
preson.age=${random.int(100)}

# 10-20的隨機數
person.name=${random.int[10,20]}

七、Environment

這種方式是經過依賴注入Spring的Environment類實現的,並經過該類的getProperty方法配置的值:
@RestController
@RequestMapping("/demo/")
public class DemoController {

    @Autowired
    private Environment environment;

    @RequestMapping("/printPerson.do")
    public String printPerson() {
        String personName = environment.getProperty("person.name");
        return personName;
    }

}

另外在測試時發現一個小坑值得注意,當配置文件中的 person.name 值採用了 ${random.value},並綁定到 Person 類中,你會發現 environment 再每次獲取 person.name 的值時是隨機的,可是Person類中經過person.name賦予的值只是第一次的值,以後將不會主動改變:
@RestController
@RequestMapping("/demo/")
public class DemoController {

    @Autowired
    private Person person;

    @Autowired
    private Environment environment;

    @RequestMapping("/printPerson.do")
    public String printPerson() {
        String nameFromClass = person.getName();
        String nameFromEnv = environment.getProperty("person.name");
        System.out.println("class: " + nameFromClass);
        System.out.println("env: " + nameFromEnv);
        return nameFromEnv;
    }

}

分別訪問三次,獲得輸出以下:
class: 80c628c7948c4270f831956945a0f26e
env: d8ff3f804268a929d365c663ade6894c
class: 80c628c7948c4270f831956945a0f26e
env: 9351315473098298f8416dae16bd1acb
class: 80c628c7948c4270f831956945a0f26e
env: ef78a4148b049c3fc25a71bddb560715


八、多環境配置 application-{profile}

咱們在實際開發時,開發環境配置、測試環境配置、正式生產環境配置,配置信息都是不同的(如開發環境的Tomcat端口是8080,生產環境的Tomcat端口則是8089),在頻繁修改配置的過程當中很容易出錯。SpringBoot提供了更加簡單的方式來解決這種問題,即經過配置多份不一樣環境下的配置文件。如原來僅有 application.yml,如今則新增三項,分別命名爲:
  • application-dev.yml
  • application-test.yml
  • application-prod.yml

而在主配置文件 application.yml 中,則經過屬性 spring.profiles.active 來指定使用哪份配置文件,如在開發時則指定 spring.profiles.active=dev,生產環境時  spring.profiles.active=prod

也能夠在命令行啓動時進行配置,這樣哪怕從新部署也不須要修改application.yml:
java -jar xxx.jar --spring.profiles.active=prod

九、加載多個自定義配置文件

咱們固然喜歡多項配置能獨立在不一樣的配置文件中進行管理,隔離而清晰,這就要求SpringBoot可以加載多個配置文件。如咱們在 src/main/resource 下新建目錄 config,新建配置文件 person.properties:

那麼咱們須要在Person類的註解上新增兩個註解:@Configuration 和 @PropertySource,其中用 @PropertySource 註解中的 value 屬性來指定須要讀取的配置文件的路徑,以下:
@Component
@Configuration
@PropertySource("classpath:config/person.properties")
@ConfigurationProperties(prefix = "person")
public class Person {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

這裏再也不使用 person.yml 做爲配置文件,是由於 @PropertySource 註解不支持YAML文件格式,官方說明 「YAML files cannot be loaded by using the @PropertySource annotation. So, in the case that you need to load values that way, you need to use a properties file.」   看來在SpringBoot中,做爲配置文件,仍是使用 .properties 更爲兼容

十、打包jar時須要注意的自定義配置文件打包

在IDE上運行時正常,在打包項目爲jar時再運行就提醒找不到配置文件,而這些配置文件每每是咱們自定義的。咱們到打包後的jar中目錄下 BOOT-INF/classes 中發現,自定義的配置文件沒有打包進來,這時須要注意,在pom.xml中添加 <resource>:
<build>
    <!-- 打包資源文件 -->
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*</include>
            </includes>
        </resource>
    </resources>
</build>

其中 <include> 中的 **/* 表示通配符,全部目錄下的全部文件,你也能夠 **/*.properties 諸如此類。

十一、@Configuration 和 @Bean

這個具體來講更應該是bean的註解配置方式:
  • @Configuration 標註在類上,至關於spring的xml配置文件中的 <beans>,做用爲配置spring容器(應用上下文)

那麼相應的
  • @Bean 標註在方法上(返回某個實例的方法),等價於spring的xml配置文件中的 <bean>,做用爲註冊bean對象


十二、參考連接

相關文章
相關標籤/搜索