@Value无法读取指定@PropertySource值,多配置文件含同名键
问题原因
Spring中@PropertySource会将配置文件的键值对加载到全局Environment中,当两个配置文件存在相同key(比如这里的param)时,后加载的配置会覆盖先加载的。由于Spring容器初始化时,两个@Component对应的@PropertySource都会被处理,application-e2.properties的配置后生效,导致全局的param值被覆盖为e2Test,因此两个类通过@Value("${param}")获取的都是这个全局值。
解决方案
方案一:使用@ConfigurationProperties加前缀(推荐)
通过给配置项添加不同前缀,让每个类绑定专属的配置,避免键值冲突。
- 修改配置文件
application-e1.properties:
e1.param=e1Test
application-e2.properties:
e2.param=e2Test
- 修改实体类
EmployeeDev:
@Component @PropertySource("classpath:application-e1.properties") @ConfigurationProperties(prefix = "e1") public class EmployeeDev { private String param; public String getParam() { return param; } public void setParam(String param) { this.param = param; } }
EmployeeTest:
@Component @PropertySource("classpath:application-e2.properties") @ConfigurationProperties(prefix = "e2") public class EmployeeTest { private String param; public String getParam() { return param; } public void setParam(String param) { this.param = param; } }
方案二:自定义PropertySourcesPlaceholderConfigurer隔离配置
为每个配置文件单独创建配置类,生成专属的配置解析器,让每个实体类使用独立的配置源。
- 创建配置类
EmployeeDevConfig:
@Configuration @PropertySource("classpath:application-e1.properties") public class EmployeeDevConfig { @Bean public static PropertySourcesPlaceholderConfigurer devPropertyConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } @Bean public EmployeeDev employeeDev() { return new EmployeeDev(); } }
EmployeeTestConfig:
@Configuration @PropertySource("classpath:application-e2.properties") public class EmployeeTestConfig { @Bean public static PropertySourcesPlaceholderConfigurer testPropertyConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } @Bean public EmployeeTest employeeTest() { return new EmployeeTest(); } }
- 修改实体类(移除
@Component和@PropertySource)EmployeeDev:
public class EmployeeDev { @Value("${param}") String param; public String getParam() { return param; } public void setParam(String param) { this.param = param; } }
EmployeeTest:
public class EmployeeTest { @Value("${param}") String param; public String getParam() { return param; } public void setParam(String param) { this.param = param; } }
方案三:通过Environment手动获取指定配置源(不推荐)
遍历Environment中的配置源,手动提取对应文件的属性值,这种方式代码繁琐,仅作参考:
@Component @PropertySource("classpath:application-e1.properties") public class EmployeeDev { @Autowired private Environment env; public String getParam() { for (PropertySource<?> source : ((AbstractEnvironment) env).getPropertySources()) { if (source.getName().contains("application-e1.properties")) { return (String) source.getProperty("param"); } } return null; } }
内容的提问来源于stack exchange,提问作者Ankitha Gowda
相关产品推荐
相关产品推荐

