springboot 讀取配置文件方式
------------------------------------------------------------------------------------------------------------
application.properties、application.yml 或自定義配置文件。以下是幾種常用的讀取方式:一、默認配置文件(application.properties/application.yml)
src/main/resources 目錄下的 application.properties 或 application.yml 文件,可直接通過注解讀取。1. 使用 @Value 注解
application.yml 配置:user:
name: "張三"
age: 20
hobbies: ["籃球", "游戲"]
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class UserConfig {
// 讀取普通屬性
@Value("${user.name}")
private String userName;
@Value("${user.age}")
private Integer age;
// 讀取數組/集合
@Value("${user.hobbies}")
private List<String> hobbies;
// getter/setter
}
2. 使用 @ConfigurationProperties 綁定對象
- 定義配置類并添加
@ConfigurationProperties注解,指定前綴。 - 類中字段名與配置文件中的 key 對應(支持駝峰命名)。
application.yml 配置:user:
name: "張三"
age: 20
address:
city: "北京"
street: "朝陽路"
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "user") // 綁定前綴為 user 的配置
public class UserProperties {
private String name;
private Integer age;
private Address address; // 嵌套對象
// 內部類(對應嵌套配置)
public static class Address {
private String city;
private String street;
// getter/setter
}
// getter/setter
}
- 需要添加
getter/setter方法,否則無法綁定。 - 若 IDE 提示警告,可添加依賴解決:
xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
二、讀取自定義配置文件
custom.properties)中,需通過 @PropertySource 指定文件路徑。src/main/resources/custom.properties 配置:custom.key=hello
custom.value=world
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource("classpath:custom.properties") // 指定自定義配置文件
public class CustomConfig {
@Value("${custom.key}")
private String key;
@Value("${custom.value}")
private String value;
// getter/setter
}
@PropertySource默認不支持yml文件,若需讀取yml,需自定義解析器。
三、通過 Environment 接口讀取
Environment 接口可動態獲取配置,適用于需要在代碼中靈活讀取的場景。import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class EnvConfig {
@Resource
private Environment env;
public void getConfig() {
String userName = env.getProperty("user.name"); // 讀取 user.name
Integer age = env.getProperty("user.age", Integer.class); // 指定類型
String defaultValue = env.getProperty("user.gender", "未知"); // 默認值
}
}
四、多環境配置
spring.profiles.active 指定環境,讀取對應環境的配置文件(如 application-dev.yml、application-prod.yml)。-
創建
application-dev.yml(開發環境):yamlserver: port: 8080 -
創建
application-prod.yml(生產環境):yamlserver: port: 80 -
在
application.yml中指定激活的環境:yamlspring: profiles: active: dev # 激活開發環境
總結
- 簡單配置:用
@Value。 - 復雜 / 關聯配置:用
@ConfigurationProperties(推薦)。 - 自定義文件:配合
@PropertySource。 - 動態讀取:用
Environment接口。
------------------------------------------------------------------------------------------------------------
一、基于默認配置文件(application.properties/application.yml)
src/main/resources 目錄下的默認配置文件(application.properties 或 application.yml),無需額外配置即可讀取。1. @Value 注解:直接注入簡單配置
${key} 表達式綁定配置值。application.yml 配置:app:
name: "我的應用"
port: 8080
enabled: true
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component // 需納入 Spring 容器管理
public class AppConfig {
// 注入字符串
@Value("${app.name}")
private String appName;
// 注入數字
@Value("${app.port}")
private Integer port;
// 注入布爾值
@Value("${app.enabled}")
private Boolean enabled;
// 注入時指定默認值(若配置中無該 key,使用默認值)
@Value("${app.version:1.0.0}")
private String version;
// getter/setter
}
@Value只能注入到 Spring 容器管理的 Bean 中(如@Component、@Service等標注的類)。- 支持 SpEL 表達式(如
${app.port + 100})。
2. @ConfigurationProperties:綁定對象(推薦復雜配置)
- 定義配置類,用
@ConfigurationProperties(prefix = "前綴")指定配置的前綴。 - 類中字段名與配置文件中的
key對應(支持駝峰命名映射,如配置user-name對應字段userName)。 - 必須提供
getter/setter方法(Spring 通過 setter 注入值)。
application.yml 配置:database:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mydb
username: root
password: 123456
pool:
max-size: 20
min-idle: 5
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "database") // 綁定前綴為 database 的配置
public class DatabaseProperties {
private String driverClassName; // 對應 driver-class-name
private String url;
private String username;
private String password;
private Pool pool; // 嵌套對象,對應 pool 子配置
// 嵌套類:對應 pool 子配置
public static class Pool {
private Integer maxSize; // 對應 max-size
private Integer minIdle; // 對應 min-idle
// getter/setter
}
// 必須提供所有字段的 getter/setter
public String getDriverClassName() { return driverClassName; }
public void setDriverClassName(String driverClassName) { this.driverClassName = driverClassName; }
// ... 其他 getter/setter
}
spring-boot-configuration-processor 依賴可生成配置元數據,支持 IDE 自動提示:<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
二、讀取自定義配置文件
configs/custom.properties),需通過 @PropertySource 注解指定文件路徑。src/main/resources/configs/custom.properties 配置:custom.id=100
custom.desc=這是自定義配置
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource(value = "classpath:configs/custom.properties") // 指定自定義文件路徑
public class CustomConfig {
@Value("${custom.id}")
private Integer id;
@Value("${custom.desc}")
private String desc;
// getter/setter
}
@PropertySource默認僅支持properties格式文件;若需讀取yml文件,需自定義PropertySourceFactory(可參考 Spring 官方文檔)。- 路徑前綴
classpath:表示從類路徑(resources目錄)下讀取。
三、通過 Environment 接口動態讀取
Environment 是 Spring 提供的環境配置接口,可動態獲取配置值,適合需要在代碼中靈活讀取配置的場景(如根據條件動態獲取不同 key 的配置)。import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class EnvReader {
@Resource // 注入 Environment 實例
private Environment env;
public void readConfig() {
// 讀取字符串
String appName = env.getProperty("app.name");
// 讀取指定類型(自動轉換,失敗拋異常)
Integer port = env.getProperty("app.port", Integer.class);
// 讀取時指定默認值(若配置不存在,返回默認值)
String version = env.getProperty("app.version", "1.0.0");
// 讀取布爾值(支持 "true"/"false"、"on"/"off"、"yes"/"no" 等)
Boolean enabled = env.getProperty("app.enabled", Boolean.class, false);
}
}
四、總結
| 方式 | 適用場景 | 優點 | 缺點 |
|---|---|---|---|
@Value |
零散的簡單配置(單個 key) | 簡單直觀,代碼侵入性低 | 配置多時代碼冗余,不支持復雜對象綁定 |
@ConfigurationProperties |
一組相關的復雜配置(對象、嵌套結構) | 結構化強,支持對象綁定,便于維護 | 需要定義專門的配置類,需寫 getter/setter |
@PropertySource + @Value |
讀取自定義配置文件(非默認文件) | 支持自定義文件路徑 | 默認不支持 yml,需額外處理 |
Environment |
動態讀取、條件性讀取配置 | 靈活,可在代碼中動態獲取 | 需手動處理類型轉換,代碼稍繁瑣 |
@ConfigurationProperties 處理復雜配置,@Value 處理簡單配置,結合多環境配置文件(如 application-dev.yml)實現環境隔離,最大化配置的可維護性。------------------------------------------------------------------------------------------------------------
一、讀取環境變量(Environment Variables)
export、Windows 的 set),Spring Boot 可直接讀取,常用于容器部署時動態傳遞參數。1. 直接讀取環境變量
(1)@Value 注解
APP_PORT),讀取時用 ${環境變量名} 即可。import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class EnvVarReader {
// 讀取環境變量 APP_NAME
@Value("${APP_NAME:默認應用}") // 冒號后為默認值
private String appName;
// 讀取環境變量 DB_PORT(數字類型)
@Value("${DB_PORT:3306}")
private Integer dbPort;
// getter/setter
}
(2)@ConfigurationProperties 綁定
# Linux/Mac 終端
export MYSQL_URL=jdbc:mysql://localhost:3306/db
export MYSQL_USER=root
export MYSQL_PWD=123456
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "mysql") // 匹配 MYSQL_ 前綴的環境變量
public class MysqlProperties {
private String url; // 對應 MYSQL_URL
private String user; // 對應 MYSQL_USER
private String pwd; // 對應 MYSQL_PWD(環境變量是 MYSQL_PWD,字段名 pwd)
// getter/setter
}
_)會自動映射為配置類中的駝峰命名(如 MYSQL_MAX_POOL 對應 maxPool 字段)。(3)Environment 接口
getProperty 方法動態讀取環境變量:import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class EnvInterfaceReader {
@Resource
private Environment env;
public String getDbUrl() {
// 讀取環境變量 DB_URL,返回默認值 if 不存在
return env.getProperty("DB_URL", "jdbc:mysql://localhost:3306/default");
}
}
二、讀取系統屬性(System Properties)
-D 指定的參數),Spring Boot 同樣會自動識別。示例:通過 -D 指定系統屬性
java -Dapp.mode=prod -Dserver.port=8081 -jar myapp.jar
// @Value 讀取
@Value("${app.mode:dev}")
private String appMode;
// Environment 讀取
String port = env.getProperty("server.port"); // 返回 "8081"
三、讀取外部配置文件
src/main/resources 下的默認配置文件,Spring Boot 還能讀取外部路徑的配置文件(如服務器上的 /etc/config 目錄),適合生產環境中動態修改配置。1. 外部配置文件的默認加載路徑(優先級從高到低)
- 命令行參數指定的配置(如
--spring.config.location=xxx); - 服務器當前目錄下的
config/子目錄(./config/); - 服務器當前目錄(
./); - 類路徑下的
config/子目錄(classpath:/config/); - 類路徑根目錄(
classpath:/)—— 即項目內的resources目錄。
2. 自定義外部配置文件路徑
/opt/app/config/),可通過以下方式指定:(1)命令行參數指定
--spring.config.location 或 --spring.config.additional-location 指定:# 方式1:覆蓋默認配置路徑(僅加載指定文件)
java -jar myapp.jar --spring.config.location=/opt/app/config/application-prod.yml
# 方式2:追加配置路徑(在默認路徑基礎上額外加載)
java -jar myapp.jar --spring.config.additional-location=/opt/app/config/
(2)環境變量指定
SPRING_CONFIG_LOCATION 指定:# Linux/Mac
export SPRING_CONFIG_LOCATION=/opt/app/config/
java -jar myapp.jar
四、讀取容器掛載的配置文件(Docker 場景)
volume 掛載外部配置文件到容器內,Spring Boot 可直接讀取掛載的文件。示例:Docker 部署時掛載配置
- 宿主機配置文件路徑:
/host/config/application.yml; - 啟動容器時掛載:
bash
docker run -d \ -v /host/config:/app/config \ # 將宿主機 /host/config 掛載到容器 /app/config -e SPRING_PROFILES_ACTIVE=prod \ # 環境變量指定激活環境 myapp:latest - 容器內的 Spring Boot 會自動讀取
/app/config/application-prod.yml(因掛載路徑在默認加載路徑./config/下)。
五、外部配置的優先級順序
- 命令行參數(
--key=value); - 系統屬性(
-Dkey=value); - 操作系統環境變量;
- 外部配置文件(如
./config/目錄下的文件); - 內部配置文件(
classpath:/config/、classpath:/); - 配置類中通過
@PropertySource指定的文件; - 默認屬性(如
SpringApplication.setDefaultProperties)。
六、總結
- 環境變量:適合容器化部署時傳遞參數,通過
@Value、@ConfigurationProperties或Environment讀取; - 系統屬性:適合 JVM 級別的臨時配置,通過
-D指定,讀取方式同環境變量; - 外部配置文件:適合生產環境中持久化的復雜配置,可通過默認路徑或
spring.config.location指定; - 優先級:命令行參數 > 系統屬性 > 環境變量 > 外部文件 > 內部文件,確保部署時能靈活覆蓋配置。
------------------------------------------------------------------------------------------------------------
Environment 和 System Properties(系統屬性) 都是讀取配置信息的重要方式,但它們的定位、來源和使用場景有顯著區別。下面詳細對比并說明兩者的關系與用法:一、System Properties(系統屬性)
1. 定義
System.getProperties() 訪問。- 來源:
- JVM 啟動時通過
-D參數指定(如java -Dserver.port=8080 -jar app.jar); - 代碼中通過
System.setProperty("key", "value")動態設置; - JVM 內置的默認屬性(如
java.version、user.home等)。
- JVM 啟動時通過
2. 特點
- 作用范圍:全局生效,屬于當前 JVM 進程的配置;
- 讀取方式:
- 原生 API:
System.getProperty("key")或System.getProperties(); - Spring 中可通過
Environment間接讀取(見下文);
- 原生 API:
- 優先級:在 Spring 的配置優先級中,系統屬性高于環境變量、內部配置文件等(僅低于命令行參數)。
3. 示例
// 讀取系統屬性(原生方式)
String port = System.getProperty("server.port"); // 讀取 -Dserver.port=8080
// 設置系統屬性
System.setProperty("app.mode", "prod");
二、Environment 接口
1. 定義
Environment 是 Spring 框架提供的 環境配置接口,統一管理應用的所有配置源(包括系統屬性、環境變量、配置文件、命令行參數等),是 Spring 中訪問配置的核心入口。2. 核心能力
- 整合多配置源:聚合系統屬性、環境變量、
application.yml、命令行參數等配置,提供統一的讀取接口; - ** Profiles 支持 **:管理多環境(如
dev/prod)的配置激活與切換; - 類型轉換:支持將配置值轉換為指定類型(如
Integer、Boolean); - 默認值支持:讀取時可指定默認值,避免配置不存在時的空指針問題。
3. 讀取方式
@Resource 或 @Autowired 注入 Environment 實例,調用其方法讀取配置:import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class ConfigReader {
@Resource
private Environment env;
public void readConfigs() {
// 讀取系統屬性(如 -Dapp.name=myapp)
String appName = env.getProperty("app.name");
// 讀取環境變量(如 export DB_HOST=localhost)
String dbHost = env.getProperty("DB_HOST");
// 讀取配置文件中的值(如 application.yml 中的 server.port)
Integer port = env.getProperty("server.port", Integer.class);
// 讀取時指定默認值
String mode = env.getProperty("app.mode", "dev");
}
}
三、Environment 與 System Properties 的關系
-
包含關系:System Properties 是
Environment管理的 配置源之一。Environment會自動整合系統屬性,并提供統一的getProperty()方法訪問,無需區分配置來自系統屬性還是其他源(如環境變量、配置文件)。 -
優先級體現:當不同配置源存在同名 key 時,
Environment會按照 Spring 的優先級規則返回值。例如:- 若系統屬性(
-Dapp.name=test)和配置文件(app.name=dev)都定義了app.name,env.getProperty("app.name")會返回系統屬性的值(test),因為系統屬性優先級更高。
- 若系統屬性(
-
使用場景差異:
- 直接用
System.getProperty():適合非 Spring 環境,或需要繞過 Spring 配置優先級直接讀取 JVM 系統屬性的場景; - 用
Environment:適合 Spring 環境中,需要統一處理各種配置源(系統屬性、環境變量、配置文件等)的場景,更符合 Spring 的設計理念。
- 直接用
四、總結
| 維度 | System Properties | Environment 接口 |
|---|---|---|
| 本質 | JVM 級別的鍵值對配置 | Spring 管理的多配置源統一接口 |
| 配置來源 | 僅 JVM 系統屬性(-D 參數、System.set) |
系統屬性、環境變量、配置文件、命令行參數等 |
| 讀取方式 | System.getProperty() |
env.getProperty() |
| 依賴環境 | 無(Java 原生) | 依賴 Spring 容器 |
| 核心優勢 | 輕量,直接訪問 JVM 配置 | 統一整合多配置源,支持類型轉換和 Profiles |
Environment,因為它能無縫整合各種配置源,且符合 Spring 的生態設計;只有在需要直接操作 JVM 系統屬性(如非 Spring 環境或特殊場景)時,才直接使用 System.getProperty()。------------------------------------------------------------------------------------------------------------
1. 命令行參數(最高優先級)
--key=value),優先級最高,會覆蓋其他所有配置源的同名配置。示例:java -jar myapp.jar --server.port=8081 --spring.profiles.active=prod
server.port 和 spring.profiles.active 會覆蓋其他源的同名配置。2. ServletContext 初始化參數
ServletContext 配置的初始化參數(如在 web.xml 或 Spring Boot 中通過 ServletContextInitializer 配置)。示例:@Bean
public ServletContextInitializer servletContextInitializer() {
return servletContext -> {
servletContext.setInitParameter("app.mode", "prod"); // 配置參數
};
}
3. JNDI 屬性(Java:comp/env)
4. Java 系統屬性(System Properties)
-D 參數在啟動時指定的 JVM 系統屬性,或通過 System.setProperty() 動態設置的屬性。示例:java -Dserver.port=8082 -jar myapp.jar # 啟動時指定
System.setProperty("app.name", "myapp");
5. 操作系統環境變量
export、Windows 的 set)。示例:# Linux/Mac
export SPRING_PROFILES_ACTIVE=prod
java -jar myapp.jar
6. RandomValuePropertySource 隨機值
random.* 生成的隨機值(如 random.int、random.uuid),僅用于生成默認值,不會被其他配置覆蓋。示例:myapp:
secret: ${random.uuid} # 生成隨機 UUID
7. 外部應用配置文件(按路徑優先級)
resources 目錄下的文件),按以下路徑順序(優先級從高到低):- (1)當前目錄下的
config/子目錄(./config/) - (2)當前目錄(
./) - (3)類路徑下的
config/子目錄(classpath:/config/) - (4)類路徑根目錄(
classpath:/)
- 例如,
./config/application.yml優先級高于./application.yml,后者又高于classpath:/config/application.yml。 - 可通過
spring.config.location或spring.config.additional-location自定義外部文件路徑,自定義路徑的優先級遵循配置的順序。
8. Profile 專屬配置文件
application-dev.yml、application-prod.properties),優先級低于外部文件,但高于公共配置文件。說明:- 若激活
dev環境(spring.profiles.active=dev),則application-dev.yml會覆蓋application.yml中的同名配置。
9. 應用內部公共配置文件
src/main/resources 目錄下的公共配置文件(application.yml 或 application.properties),所有環境共享,優先級較低。10. @PropertySource 注解引入的配置
@PropertySource 注解引入的自定義配置文件(如 @PropertySource("classpath:custom.properties")),優先級低于上述所有配置。注意:@PropertySource 默認不支持 YAML 文件,需自定義解析器。11. 默認屬性(最低優先級)
SpringApplication.setDefaultProperties() 設置的默認屬性,優先級最低,會被任何其他配置源覆蓋。示例:public static void main(String[] args) {
SpringApplication app = new SpringApplication(MyApp.class);
app.setDefaultProperties(Collections.singletonMap("server.port", "8080")); // 默認端口
app.run(args);
}
總結:優先級排序表
| 優先級(從高到低) | 配置源類型 | 示例 |
|---|---|---|
| 1 | 命令行參數 | --server.port=8081 |
| 2 | ServletContext 初始化參數 | servletContext.setInitParameter(...) |
| 3 | JNDI 屬性(Java:comp/env) | 應用服務器配置的 JNDI 參數 |
| 4 | Java 系統屬性(-D 參數) | -Dapp.mode=prod |
| 5 | 操作系統環境變量 | export SPRING_PROFILES_ACTIVE=prod |
| 6 | RandomValuePropertySource | ${random.int} |
| 7 | 外部配置文件(按路徑優先級) | ./config/application.yml |
| 8 | Profile 專屬配置文件 | application-dev.yml |
| 9 | 應用內部公共配置文件 | application.yml |
| 10 | @PropertySource 引入的配置 | @PropertySource("classpath:custom.properties") |
| 11 | 默認屬性(setDefaultProperties) | app.setDefaultProperties(...) |
關鍵原則
- 外部配置優先于內部配置:命令行、環境變量、外部文件等外部配置,優先級高于項目內部的配置文件。
- 具體環境配置優先于公共配置:
application-dev.yml會覆蓋application.yml的同名配置。 - 靈活覆蓋:部署時可通過命令行參數(最高優先級)動態修改配置,無需修改代碼或內部配置文件。
------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------

浙公網安備 33010602011771號