[轉]Spring Boot讀取配置檔案常用方式[強烈建議閱讀]

zhaozhangxiao發表於2022-05-18

目錄
一、簡介
二、依賴和配置
2.1、maven依賴
2.2、application.properties配置
三、實踐(後面的例項全部採用@PostConstruct測試)
3.1、@Value方式獲取
3.2、Environment物件獲取
3.3、@ConfigurationProperties方式獲取(強烈推薦)
3.4、@PropertySource方式獲取
3.5、原生方式獲取
結語
一、簡介
  實際開發過程中,我們經常要獲取配置檔案的值,來實現我們程式的可配置化,今天我們就來看看Spring Boot裡獲取配置檔案值的幾種方式。

二、依賴和配置
2.1、maven依賴
  本文中Spring Boot的版本為當前最新版(當前最新為2.5.2)
pom.xml

<?xml version="1.0" encoding="UTF-8"?>


4.0.0

org.springframework.boot
spring-boot-starter-parent
2.5.2

<groupId>com.alian</groupId>
<artifactId>properties</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>properties</name>
<description>Spring Boot讀取配置檔案的值</description>

<properties>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>${parent.version}</version>
    </dependency>

    <!--@PropertySource使用到-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <version>${parent.version}</version>
        <optional>true</optional>
    </dependency>

    <!--本專案也可以不引用-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>${parent.version}</version>
    </dependency>

    <!--[@Data](https://learnku.com/users/28552)或日誌使用到-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.14</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

  大家可以根據自己專案的需要進行選擇。

2.2、application.properties配置
application.properties

#如果引用了

#

#

#則配置專案名和埠
server.port=8897
server.servlet.context-path=/properties
  因為我本地是建了一個web專案

三、實踐(後面的例項全部採用@PostConstruct測試)
3.1、@Value方式獲取
語法如下:

@Value(${配置項key:預設值})
private String configValue;

注意:@Value是org.springframework.beans.factory.annotation.Value

我們在配置檔案application.properties中新增如下配置,用於測試@Value方式獲取配置檔案的值

#定義@Value的變數測試

#請求地址
value.request.url=openapi.alipay.com/gateway.do

#請求應用id
value.request.app.id=2019052960295228

#請求籤名key
value.request.sign.key=FFFFEA911121494981C5FEBA599C3A99

#請邱加密key
value.request.encrypted.key=EEEE9CA14DE545768A0BD9F1435EE507

@Value測試源程式
ValueService.java

package com.alian.properties.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

@Service
public class ValueService {

/**
 * 請求地址
 */
@Value("${value.request.url}")
private String url;

/**
 * 請求應用id
 */
@Value("${value.request.app.id}")
private String appId;

/**
 * 請求籤名key
 */
@Value("${value.request.sign.key}")
private String signKey;

/**
 * 請求加密key
 */
@Value("${value.request.encrypted.key}")
private String encryptedKey;

/**
 * 超時時間(預設值設定,當沒有獲取到配置值時,用冒號分隔,寫在冒號後面)
 */
@Value("${value.request.timeout:20}")
private int timeOut;

@PostConstruct
public void testValue() {
    System.out.println("-------------------@Value測試開始-------------------");
    System.out.println("@Value測試獲取的請求地址:" + url);
    System.out.println("@Value測試獲取的請求應用id:" + appId);
    System.out.println("@Value測試獲取的請求籤名key:" + signKey);
    System.out.println("@Value測試獲取的請求加密key:" + encryptedKey);
    //如果配置檔案未設定該key的值,則使用預設值
    System.out.println("@Value測試獲取的預設值設定:" + timeOut);
    System.out.println("-------------------@Value測試結束-------------------");
}

}

執行結果:

-------------------@Value測試開始——————-
@Value測試獲取的請求地址:openapi.alipay.com/gateway.do
@Value測試獲取的請求應用id:2019052960295228
@Value測試獲取的請求籤名key:FFFFEA911121494981C5FEBA599C3A99
@Value測試獲取的請求加密key:EEEE9CA14DE545768A0BD9F1435EE507
@Value測試獲取的預設值設定:20
-------------------@Value測試結束——————-
使用@Value方式獲取配置檔案的值,如果配置項的key不存在,也沒有設定預設值,則程式直接報錯
使用@Value方式預設值的設定方法:配置項的key後面加冒號然後寫預設值如:${配置項的key:預設值}
使用@Value方式如果是配置檔案裡配置項太多,並且使用的地方過多的時候,維護和管理不太方便
3.2、Environment物件獲取
使用很簡單,直接使用spring的註解@Autowired引入即可

@Autowired
private Environment environment;

注意:Environment 是org.springframework.core.env.Environment

我們繼續在配置檔案application.properties中新增如下配置,用於測試Environment 方式獲取配置檔案的值

#定義Environment的變數測試

#系統組
envir.system.group=Alian

#系統組
envir.system.level=1

#系統名稱
envir.system.name=administrator

#系統密碼
envir.system.password=e6fa5927cc37437ac6cbe5e988288f80

Environment測試源程式

EnvironmentService.java

package com.alian.properties.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

@Service
public class EnvironmentService {

@Autowired
private Environment environment;

@PostConstruct
public void testEnvironment() {
    System.out.println("-------------------Environment測試開始-------------------");
    System.out.println("Environment測試獲取的系統組:" + environment.getProperty("envir.system.group"));
    System.out.println("Environment測試獲取的系統級別:" + environment.getProperty("envir.system.level"));
    System.out.println("Environment測試獲取的系統名:" + environment.getProperty("envir.system.name"));
    System.out.println("Environment測試獲取的系統密碼:" + environment.getProperty("envir.system.password"));
    //如果配置檔案未設定該key的值,則使用預設值
    System.out.println("Environment測試獲取的預設值設定:" + environment.getProperty("envir.system.init", "未設定初始化引數"));
    System.out.println("-------------------Environment測試結束-------------------");
}

}

執行結果:

——————-Environment測試開始——————-
Environment測試獲取的系統組:Alian
Environment測試獲取的系統級別:1
Environment測試獲取的系統名:administrator
Environment測試獲取的系統密碼:e6fa5927cc37437ac6cbe5e988288f80
Environment測試獲取的預設值設定:未設定初始化引數
——————-Environment測試結束——————-
注意:

使用Environment物件獲取配置檔案的值,最好使用帶預設值的方法:getProperty(“配置項key”,“預設值”),避免null值
使用Environment物件還可以獲取到一些系統的啟動資訊,當然如果配置項過多也會有維護管理方面的問題
3.3、@ConfigurationProperties方式獲取(強烈推薦)
  為了更契合java的物件導向,我們採用自動配置的方式對映配置檔案屬性,配置完成後直接當做java物件即可使用。我們繼續在配置檔案application.properties中新增如下配置,用於測試@ConfigurationProperties方式獲取配置檔案的值

##定義Properties的變數測試

#作者
app.author-name=Alian

#部落格網站
app.web-url=blog.csdn.net/Alian_1223

#小程式應用id
app.micro-applet.app-id=wx4etd7e3803c6c555

#小程式應用secretId
app.micro-applet.secret-id=e6fa5627cc57437ac8cbe5e988288f80

#小程式超時時間
app.micro-applet.expire-time=3600
廢話不多少,直接新建一個配置類AppProperties.java
AppProperties.java

package com.alian.properties.config;

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

@Data
@Component
@ConfigurationProperties(value = “app”)
public class AppProperties {

/**
 * 作者名稱
 */
private String authorName = "";

/**
 * 部落格網站
 */
private String webUrl = "https://blog.csdn.net/Alian_1223";

/**
 * 小程式配置
 */
private MicroApplet microApplet;

[@Data](https://learnku.com/users/28552)
public static class MicroApplet {
    /**
     * 應用id
     */
    private String appId = "";
    /**
     * secretId
     */
    private String secretId = "";
    /**
     * 過期時間
     */
    private int expireTime = 30;
}

}

注意:

@ConfigurationProperties(value = “app”)表示的配置檔案裡屬性的字首都是app開頭
配置類上記得加上@Data和@Component註解(或者在啟動類上加上@EnableConfigurationProperties(value = AppProperties.class))
如果有內部類物件,記得加上@Data,不然無法對映資料
.properties型別檔案對映規則,短橫線(-)後面的首個字母會變成大寫,同時注意有內部類時的寫法
使用方法也很簡單,直接使用spring的註解@Autowired引入即可

@Autowired
private AppProperties appProperties;

AppProperties測試源程式
PropertiesService.java

package com.alian.properties.service;

import com.alian.properties.config.AppProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

@Service
public class PropertiesService {

@Autowired
private AppProperties appProperties;

@PostConstruct
public void testProperties() {
    System.out.println("-------------------Properties測試開始-------------------");
    System.out.println("Properties測試獲取的作者:" + appProperties.getAuthorName());
    System.out.println("Properties測試獲取的部落格地址:" + appProperties.getWebUrl());
    System.out.println("Properties測試獲取的小程式應用id:" + appProperties.getMicroApplet().getAppId());
    System.out.println("Properties測試獲取的小程式SecretId:" + appProperties.getMicroApplet().getSecretId());
    System.out.println("Properties測試獲取的小程式超時時間:" + appProperties.getMicroApplet().getExpireTime());
    System.out.println("-------------------Properties測試結束-------------------");
}

}

執行結果:

——————-Properties測試開始——————-
Properties測試獲取的作者:Alian
Properties測試獲取的部落格地址:blog.csdn.net/Alian_1223
Properties測試獲取的小程式應用id:wx4etd7e3803c6c555
Properties測試獲取的小程式SecretId:e6fa5627cc57437ac8cbe5e988288f80
Properties測試獲取的小程式超時時間:3600
——————-Properties測試結束——————-

型別轉換少,配置類可以直接定義常規型別
配置分類方便,一個地方維護,不用一個key到處寫
更符合物件導向的寫法
Spring Boot註解讀取application.properties或者application-{profile}.properties檔案時預設編碼是ISO_8859_1,讀取yaml配置檔案時使用的是UTF-8的編碼方式,如果有中文配置請使用.yml格式,或者使用我接下來的讀取方式。
3.4、@PropertySource方式獲取
  有時候我們會有一些特殊意義的配置,會單獨用一個配置檔案儲存,比如資料庫配置連線引數,同樣我們在application.properties同級目錄新建一個配置檔案alian.properties,內容如下:
alian.properties

#部落格使用者
csdn.user-name=Alian

#部落格密碼
csdn.password=123456

#部落格地址
csdn.blog-url=blog.csdn.net/Alian_1223

#部落格描敘
csdn.blog-desp=來來來,一起聊乾貨!!!

新建一個配置類ALianProperties.java來完成對映
ALianProperties.java

package com.alian.properties.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = “csdn”)
@PropertySource(value = “classpath:alian.properties”, encoding = “UTF-8”, ignoreResourceNotFound = true)
public class ALianProperties {

private String userName;

private String password;

private String blogUrl;

private String blogDesp;

}

注意:

@ConfigurationProperties(value = “csdn”)表示配置檔案裡屬性的字首都是csdn開頭
@PropertySource中value屬性表示指定配置檔案的路徑,encoding屬性表示指定的是讀取配置檔案時的編碼,記得和檔案alian.properties的編碼保持一致,ignoreResourceNotFound屬性值為true時沒找到指定配置檔案的時候不報錯
配置類上記得加上@Component註解
.yml 格式不支援@PlaceSource註解匯入配置
使用方法也很簡單,直接使用spring的註解@Autowired引入即可

@Autowired
private ALianProperties ALianProperties;

@PlaceSource測試源程式
PlaceSourceService .java

package com.alian.properties.service;

import com.alian.properties.config.ALianProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

@Service
public class PlaceSourceService {

@Autowired
private ALianProperties ALianProperties;

@PostConstruct
public void testPlaceSource() {
    System.out.println("-------------------PlaceSource測試開始-------------------");
    System.out.println("Properties測試獲取的資料庫地址:" + ALianProperties.getBlogUrl());
    System.out.println("Properties測試獲取的資料庫使用者名稱:" + ALianProperties.getUserName());
    System.out.println("Properties測試獲取的資料庫密碼:" + ALianProperties.getPassword());
    System.out.println("Properties測試獲取的資料庫連線引數:" + ALianProperties.getBlogDesp());
    System.out.println("-------------------PlaceSource測試結束-------------------");
}

}

執行結果:

——————-PlaceSource測試開始——————-
Properties測試獲取的資料庫地址:blog.csdn.net/Alian_1223
Properties測試獲取的資料庫使用者名稱:Alian
Properties測試獲取的資料庫密碼:123456
Properties測試獲取的資料庫連線引數:來來來,一起聊乾貨!!!
——————-PlaceSource測試結束——————-

3.5、原生方式獲取
原生方式大家都懂,就不過多介紹了,直接上程式碼
LoadPropertiesService.java

package com.alian.properties.service;

import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.Properties;

@Service
public class LoadPropertiesService {

@PostConstruct
public void testLoadProperties() {
    System.out.println("-------------------LoadProperties測試開始-------------------");
    Properties props = new Properties();
    try {
        InputStreamReader inputStreamReader = new InputStreamReader(Objects.requireNonNull(this.getClass().getClassLoader().getResourceAsStream("load.properties")), StandardCharsets.UTF_8);
        props.load(inputStreamReader);
    } catch (IOException e1) {
        e1.printStackTrace();
    }
    System.out.println("LoadProperties測試獲取的功能名稱:" + props.getProperty("function.name"));
    System.out.println("LoadProperties測試獲取的功能描述:" + props.getProperty("function.desp"));
    System.out.println("-------------------LoadProperties測試開始-------------------");
}

}

執行結果:

——————-LoadProperties測試開始——————-

LoadProperties測試獲取的功能名稱:loadProperties
LoadProperties測試獲取的功能描述:原生獲取配置檔案的值
——————-LoadProperties測試開始——————-

注意:

讀取流的時候指定好編碼,保證和檔案的編碼一致,否則會導致亂碼
結語
  本文主要介紹了幾種讀取配置檔案的方式,實際工作中,前面三種方式用得比較多,當然以後有了spring cloud配置中心,使用我推薦的方式結合@RefreshScope即可完成配置檔案動態重新整理。
————————————————
版權宣告:本文為CSDN博主「嘉禾嘉寧papa」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:blog.csdn.net/Alian_1223/article/d...

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章