Spring Boot屬性設置方法及優先級完整說明
官網參考:
https://docs.spring.io/spring-boot/3.4-SNAPSHOT/reference/features/external-config.html#features.external-config.files
屬性設置方法優先級順序(從高到低)
- 命令行參數(
--key=value
) - SpringApplication.setDefaultProperties(默認屬性)
- 系統屬性(
-Dkey=value
) - JNDI屬性(通過JNDI接口)
- 來自
java:comp/env
的JNDI屬性 - 操作系統環境變量(
NAME=value
) - 隨機屬性(
random.*
,需啟用或顯式配置) - 外部配置文件(
application-{profile}.properties
或application.yml
) - 內部配置文件(
application-{profile}.properties
或application.yml
) - 外部通用配置文件(
application.properties
或application.yml
) - 內部通用配置文件(
application.properties
或application.yml
) @PropertySource
注解@Value
注解@ConfigurationProperties
綁定Environment
直接獲取
代碼示例
1. 命令行參數
// 啟動命令:java -jar app.jar --name=CommandLine
@Configuration
public class CommandLineConfig {@Value("${name:Default}") private String name; // 默認值為Default@Beanpublic String getName() {return name;}
}
2. SpringApplication.setDefaultProperties
// 啟動類中設置默認屬性
public static void main(String[] args) {Map<String, Object> defaultProps = new HashMap<>();defaultProps.put("name", "SpringAppDefault");SpringApplication app = new SpringApplication(App.class);app.setDefaultProperties(defaultProps);app.run(args);
}
3. 系統屬性
// 啟動命令:java -Dname=SystemProp -jar app.jar
@Configuration
public class SystemPropConfig {@Value("${name:Default}") private String name;@Beanpublic String getName() {return name;}
}
4. JNDI屬性
// 需要JNDI服務器配置(如Tomcat)
// JNDI綁定示例(需實現JNDI環境):
// Context context = new InitialContext();
// context.bind("java:comp/env/name", "JNDIValue");@Configuration
public class JndiConfig {@Value("${name:Default}") private String name;@Beanpublic String getName() {return name;}
}
5. 操作系統環境變量
# 在操作系統中設置環境變量
export NAME=OsEnvVar
@Configuration
public class OsEnvConfig {@Value("${name:Default}") private String name;@Beanpublic String getName() {return name;}
}
6. 隨機屬性(random.*
)
# application.properties
random.name=RandomValue
@Component
public class RandomBean {@Value("${name:Default}") private String name;public String getName() {return name;}
}
7. 外部/內部配置文件(帶profile)
# 外部配置文件:application-dev.properties(優先級高于內部文件)
name=ExternalProfile
# 內部配置文件:src/main/resources/application-dev.yml
name: InternalProfile
// 啟動時指定profile:
java -jar app.jar --spring.profiles.active=dev
8. @PropertySource
@Configuration
@PropertySource("classpath:custom.properties") // 指定自定義配置文件
public class PropertySourceConfig {@Value("${name:Default}") private String name;@Beanpublic String getName() {return name;}
}
# custom.properties
name=PropertySource
9. Environment 直接獲取
@Service
public class EnvironmentService {@Autowiredprivate Environment env;public String getName() {return env.getProperty("name", "Default");}
}
對比表格
方法 | 使用方式 | 優先級 | 適用場景 | 示例代碼片段 |
---|---|---|---|---|
命令行參數 | --key=value 啟動時指定 | 最高 | 運行時動態覆蓋配置 | java -jar app.jar --name=CommandLine |
SpringApplication.setDefaultProperties | 通過代碼設置默認屬性(啟動類中配置) | 高 | 程序啟動前設置默認值 | app.setDefaultProperties(defaultProps) |
系統屬性 | -Dkey=value 啟動時指定 | 次之 | JVM 級別配置 | java -Dname=SystemProp -jar app.jar |
JNDI屬性 | 通過JNDI接口綁定(需JNDI服務器支持) | 較高 | 企業級環境(如Tomcat)中的集中配置 | new InitialContext().bind("java:comp/env/name", "JNDIValue") |
java:comp/env 的JNDI屬性 | 通過java:comp/env 前綴綁定 | 中高 | 標準化JNDI配置路徑 | @Value("${name}") 綁定到java:comp/env/name |
操作系統環境變量 | 操作系統設置環境變量(如export NAME=Value ) | 中高 | 跨平臺環境變量配置 | export NAME=OsEnvVar |
隨機屬性(random.* ) | 在配置文件中設置random.* 前綴的屬性 | 中等 | 生成隨機值(如密碼、密鑰) | random.name=RandomValue |
外部配置文件(帶profile) | 獨立于jar的application-{profile}.properties 或 application.yml | 中等 | 環境特定配置(如dev/test/prod) | src/main/resources/application-dev.properties |
內部配置文件(帶profile) | jar包內的application-{profile}.properties 或 application.yml | 中等 | 內置環境配置 | src/main/resources/application-dev.yml |
外部通用配置文件 | 獨立于jar的application.properties 或 application.yml | 中低 | 通用配置覆蓋內部文件 | src/main/resources/application.properties |
內部通用配置文件 | jar包內的application.properties 或 application.yml | 中低 | 基礎配置 | src/main/resources/application.yml |
@PropertySource | 在@Configuration 類中通過注解指定外部屬性文件 | 較低 | 自定義配置文件綁定 | @PropertySource("classpath:custom.properties") |
@Value | 直接注入字段 | 較低 | 簡單單值注入 | @Value("${name}") private String name; |
@ConfigurationProperties | 綁定POJO對象到配置前綴 | 最低 | 復雜對象配置綁定 | @ConfigurationProperties(prefix = "user") |
Environment | 通過Environment 抽象類獲取屬性 | 最低 | 需要靈活獲取多種屬性的場景 | env.getProperty("name", "Default") |
優先級驗證示例
假設同時設置以下屬性:
- 命令行參數:
--name=CommandLine
- 系統屬性:
-Dname=SystemProp
- 環境變量:
export NAME=OsEnvVar
- 配置文件:
application.properties
中設置name=ConfigFile
實際運行時,CommandLine
的值會生效,因為命令行參數的優先級最高。如果移除命令行參數,則系統屬性的值 SystemProp
會生效,依此類推。