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
@Bean
public 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;
@Bean
public 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;
@Bean
public String getName() {
return name;
}
}
5. 操作系统环境变量
# 在操作系统中设置环境变量
export NAME=OsEnvVar
@Configuration
public class OsEnvConfig {
@Value("${name:Default}")
private String name;
@Bean
public 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;
@Bean
public String getName() {
return name;
}
}
# custom.properties
name=PropertySource
9. Environment 直接获取
@Service
public class EnvironmentService {
@Autowired
private 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
会生效,依此类推。