註解@PropertySource使用 springboot

itzilong發表於2018-08-24

通過PropertySource註解載入指定的配置檔案。以及PropertySource註解與@ConfigurationProperties兩個註解的配合使用。

1、PropertySource註解載入指定的屬性檔案

Spring框架提供了PropertySource註解,目的是載入指定的屬性檔案,接下來我們看一下如何使用該註解。首先我們定義一個配置類,並在類中新增PropertySource註解,如下所示:

package com.xi.propety.propety.properties;

import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component
@PropertySource(value = {"classpath:people.properties"},ignoreResourceNotFound = false,encoding = "UTF-8",name = "people.properties")
public class PeopleProperties {

    private String name;

    private int age;

    private String history;

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

上述的程式碼目的是載入classpath路徑中的people.properties。其中encoding用於指定讀取屬性檔案所使用的編碼,我們通常使用的是UTF-8;ignoreResourceNotFound含義是當指定的配置檔案不存在是否報錯,預設是false;比如上文中指定的載入屬性檔案是people.properties。如果該檔案不存在,則ignoreResourceNotFound為true的時候,程式不會報錯,如果ignoreResourceNotFound為false的時候,程式直接報錯。實際專案開發中,最好設定ignoreResourceNotFound為false。該引數預設值為false。

value值是設定需要載入的屬性檔案,可以一次性載入多個。name的值我們設定的是people.properties。這個值在Springboot的環境中必須是唯一的,如果不設定,則值為:“class path resource [people.properties]“。

瞭解了上文所述的Resource類之後。我們再次明確一點,如果@PropertySource中如果沒有設定name值,則name值的生成規則是:根據value值查詢到最終封裝的Resource子類,然後呼叫具體的Resource子類例項物件中的getDescription方法,getDescription方法的返回值為最終的name值。

2、PropertySource註解載入指定的屬性檔案測試

上文我們設定了PropertySource註解來載入"classpath:people.properties"檔案。該檔案的目錄結構如下圖所示:

people.properties內容如下:

female.age=10
female.name=xiaohua
female.history=beijing

下面開始書寫Springboot的啟動類,如下所示:

package com.xi.propety.propety;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

import java.util.logging.Logger;

@SpringBootApplication
public class PropetyApplication {

	public static void main(String[] args) {
		SpringApplication springApplication = new SpringApplication(PropetyApplication.class);
		ConfigurableApplicationContext context = springApplication.run(args);
		Object bean = context.getBean(PeopleProperties.class);
		if(bean==null){
			System.out.println("bean為null");
		}else{
			System.out.println(bean.toString());
		}
		String age = context.getEnvironment().getProperty("female.age");
		System.out.println("age的值為:"+age);
	}
}

執行上述的程式碼,程式的輸出如下:

PeopleProperties{name='null', age=0, history='null'}
age的值為:10

奇怪了,怎麼bean是空呢?PropertySource註解不是已經將people.properties檔案載入到當前的環境中了嗎?而PropertySource註解已經將people.properties檔案載入到當前的環境中。

三、PropertySource註解讀取指定檔案並將屬性注入到配置類

Spring中提供了@Value註解,用於將配置檔案中的屬性值讀取出來並設定到相應的屬性中。在這裡我們學習一下如何使用@Value註解。同樣的還是以上文的兩個類為例進行詳細說明,首先需要修改PeopleProperties.java類,修改部分如下所示:

package com.xi.propety.propety;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component
@PropertySource(value = {"classpath:people.properties"},ignoreResourceNotFound = false,encoding = "UTF-8",name = "people.properties")

public class PeopleProperties {

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

    private int age;

    private String history;

    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;
    }

    public String getHistory() {
        return history;
    }

    public void setHistory(String history) {
        this.history = history;
    }

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

上述的類中,在url欄位中增加了@Value註解,並指定了SPEL表示式為${female.name}。再次執行springboot啟動類,控制檯的輸出為內容如下:

PeopleProperties{name='xiaohua', age=0, history='null'}
age的值為:10

表明確實可以通過@Value進行屬性值的注入。但是使用@Value註解方式有一個不太友好的地方就是,當專案中有大量的屬性進行配置的時候,我們需要一個個的在類的欄位中增加@Value註解,這樣確實很費勁,不過我們可以通過Springboot提供的@ConfigurationProperties註解解決這個問題。

四、ConfigurationProperties註解使用

@ConfigurationProperties是類級別的註解,具體使用方式如下:

package com.xi.propety.propety;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component
@PropertySource(value = {"classpath:people.properties"},ignoreResourceNotFound = false,encoding = "UTF-8",name = "people.properties")
@ConfigurationProperties(prefix = "female",ignoreUnknownFields=true,ignoreInvalidFields=true)
public class PeopleProperties {

    private String name;

    private int age;

    private String history;

    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;
    }

    public String getHistory() {
        return history;
    }

    public void setHistory(String history) {
        this.history = history;
    }

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

上述程式碼中,在PeopleProperties類中增加了ConfigurationProperties註解,並且指明瞭屬性的字首為female。這樣Springboot在處理的時候,會去掃描當前類中的所有欄位並進行屬性的查詢以及組裝。比如我們配置的prefix = "female",PeopleProperties類中有一個name欄位,則female欄位需要匹配的屬性是prefix+欄位=female.name。

那不僅有個疑問?如果指定的欄位沒有找到屬性怎麼辦呢?這個可以進行如下的配置:

@ConfigurationProperties(prefix = "female",ignoreUnknownFields=true,ignoreInvalidFields=true)  

ignoreUnknownFields:忽略未知的欄位。

ignoreInvalidFields:是否忽略驗證失敗的欄位。這個怎麼理解呢?比如我們在配置檔案中配置了一個字串型別的變數,類中的欄位是int型別,那肯定會報錯的。如果出現這種情況我們可以容忍,則需要配置該屬性值為true。該引數值預設為false。

列印日誌如下:

PeopleProperties{name='xiaohua', age=10, history='beijing'}
age的值為:10

注意使用該註解,bean一定有Set與Get方法,否則取不出對應的屬性值。

Demo下載地址:https://download.csdn.net/download/zhizhuodewo6/10625338

相關文章