Spring 环境与配置文件

最后更新: 2026-04-08 03:18:35 +0800 +0800
原文以英文撰写。您正在阅读AI翻译版本。

Spring 的 Environment 结合了两个关注点:解析配置属性,以及确定哪些 Bean 定义配置文件处于激活状态。核心框架定义了抽象以及标准 JVM/Servlet 来源;Spring Boot 则增加了自己的外部配置来源和优先级规则。

属性源与优先级 #

可配置环境在 MutablePropertySources 中维护按顺序排列的 PropertySource<?> 对象。解析会从优先级最高的源开始,依次向优先级较低的源搜索,并返回包含所请求键的第一个源中的值。显式命名和排序属性源,可以避免配置随注册顺序变化:

java
ConfigurableEnvironment environment = context.getEnvironment();
environment.getPropertySources().addFirst(
    new MapPropertySource("deployment", Map.of("orders.timeout", "2s")));

StandardEnvironment 包含 JVM 系统属性和操作系统环境变量。StandardServletEnvironment 增加 Servlet 配置、Servlet 上下文参数,并可选地增加 JNDI 源。在处理配置类时,@PropertySource 可以添加属性资源。

源的顺序是一项策略,而不是一条要求每个文件、JVM 属性或环境变量都必须获胜的内在规则。Spring Boot 定义了一个更大的、已文档化的顺序,其中包括配置数据和命令行参数。测试应添加显式的测试源,而不应依赖开发者机器的环境。

解析、默认值与类型 #

PropertyResolver API 支持直接查找和类型化查找:

java
Duration timeout =
    environment.getProperty("orders.timeout", Duration.class, Duration.ofSeconds(1));

类型化访问会委托给已配置的转换服务。占位符语法支持 ${orders.timeout},以及 ${orders.timeout:1s} 这样的回退值。上下文具有适当的嵌入值解析器时,@Value 会使用占位符解析;在显式的非 Boot 配置中,PropertySourcesPlaceholderConfigurer 提供该功能。

只有当默认值在运行层面有效时,回退值才适用。可以在 Bean 使用必需配置之前声明并校验它:

java
environment.setRequiredProperties("database.url", "database.user");
environment.validateRequiredProperties();

未解析的必需占位符应使启动失败,而不是静默选择不适合生产环境的值。密钥应通过受控的属性源输入,并且在诊断解析问题时不得打印。

配置文件表达式 #

@Profile 使组件或配置类根据激活的配置文件进行条件化。配置文件表达式支持名称、使用 ! 的否定、使用 & 的合取、使用 | 的析取以及括号:

java
@Configuration
@Profile("production & !maintenance")
class ProductionConfiguration {
}

对于 @Profile({"blue", "green"}) 这样的数组,只要任一元素匹配,组件就会被激活。未指定配置文件的定义无论激活集合为何都保持可用。

未显式激活任何配置文件时,Spring 使用默认配置文件集合,其初始值包含 default。spring.profiles.default 可以更改该集合。因此,标记为 @Profile("default") 的 Bean 是有条件的;当另一个配置文件处于激活状态时,它不会成为无条件的回退实现。

激活配置文件 #

可以在刷新之前以编程方式选择配置文件:

java
var context = new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("integration");
context.register(TestConfiguration.class);
context.refresh();

配置文件也可以来自 spring.profiles.active 属性。JVM 参数 -Dspring.profiles.active=production 可与核心标准环境配合使用。根据 Boot 的外部配置规则,Spring Boot 还接受命令行配置以及诸如 SPRING_PROFILES_ACTIVE 这样的宽松环境变量名称。根据使用 setActiveProfiles 还是 addActiveProfile,编程调用会替换环境的激活集合,或向其中添加配置文件。

确定性配置 #

在生产环境和测试中应用相同的显式策略:

  1. 记录源名称和优先级。
  2. 在刷新上下文之前激活配置文件。
  3. 对测试拥有的值使用 @TestPropertySource 或 @DynamicPropertySource。
  4. 在专门的配置测试中断言关键的已解析值。
  5. 保持配置文件的粒度较粗;对于值使用属性,而不是为每种配置组合创建一个配置文件。

主要参考资料 #

评论

在 GitHub 上阅读或评论(发表评论需要登录)