You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在纯Spring Framework(非Spring Boot)集成测试中,如何让PropertySourcesPlaceholderConfigurer优先搜索系统属性?

在纯Spring Framework(非Spring Boot)集成测试中,如何让PropertySourcesPlaceholderConfigurer优先搜索系统属性?

哎,这个问题我太熟了!之前在纯Spring项目里做集成测试时也踩过这个坑——默认情况下PropertySourcesPlaceholderConfigurer并不会优先用系统属性,得咱们手动调整配置才行。

首先得给你理清楚默认逻辑:Spring的Environment里默认的属性源顺序中,系统属性的优先级其实是低于配置文件这类属性源的,所以占位符解析时会先找配置文件里的值,找不到才会看系统属性。但咱们要反过来,让系统属性先被搜索。

最简单直接的办法就是自定义PropertySourcesPlaceholderConfigurer的Bean,给它设置系统属性覆盖模式:

  • 首先在你的测试配置类里,定义一个静态的PropertySourcesPlaceholderConfigurer Bean方法(必须是静态的!因为它是BeanFactoryPostProcessor,Spring要在其他Bean实例化前就处理它)
  • 调用setSystemPropertiesMode方法,传入PropertySourcesPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_OVERRIDE这个常量,它的值是2,作用就是让系统属性优先,覆盖其他属性源里的同名值

给你贴个代码示例,一看就懂:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;

@Configuration
public class TestIntegrationConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfigurer() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        // 开启系统属性优先模式
        configurer.setSystemPropertiesMode(PropertySourcesPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_OVERRIDE);
        return configurer;
    }
}

这样设置之后,当Spring解析${xxx}这类占位符时,会先去系统属性里找对应的值,找到就直接用,找不到再去其他属性源(比如配置文件)里搜,完美实现你要的优先级。

要是你需要更精细的属性源顺序控制(比如还要调整其他属性源的位置),也可以手动操作Environment里的PropertySources,把systemProperties移到最前面,代码大概是这样:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.StandardEnvironment;

@Configuration
public class TestIntegrationConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfigurer() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        ConfigurableEnvironment environment = new StandardEnvironment();
        MutablePropertySources propertySources = environment.getPropertySources();
        
        // 把systemProperties属性源移到第一个位置
        String systemPropsName = StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME;
        if (propertySources.contains(systemPropsName)) {
            var systemProps = propertySources.remove(systemPropsName);
            propertySources.addFirst(systemProps);
        }
        
        configurer.setEnvironment(environment);
        return configurer;
    }
}

不过一般来说,第一种方法就足够解决问题了,简单又高效。

备注:内容来源于stack exchange,提问作者Harold L. Brown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 14:18:01