Spring容器解析${key}占位符的核心是PropertySourcesPlaceholderConfigurer,Spring Boot默认自动配置,传统Spring需手动注册;@PropertySource仅注入属性源,不替代占位符解析。

Spring 容器加载外部属性占位符(如 ${key})的核心是注册并启用 PropertySourcesPlaceholderConfigurer —— 它负责解析占位符、合并多源属性、处理默认值和类型转换。Spring Boot 默认已自动配置该类,但 Spring Framework(XML 或纯 Java 配置)需手动引入。
Spring Boot 项目:默认已生效,无需额外配置
只要把 application.properties 或 application.yml 放在 src/main/resources 下,@Value("${xxx}") 就能直接使用。Spring Boot 启动时会自动注册 PropertySourcesPlaceholderConfigurer(实际是其增强版 ConfigurationPropertySourcesPostProcessor),并加载所有标准配置源。
- 支持默认值写法:
@Value("${db.port:3306}") - 支持嵌套表达式:
@Value("${profile.active:${spring.profiles.active:dev}}") - 未定义且无默认值时,启动报错(
IllegalArgumentException)
传统 Spring(非 Boot):需显式注册 Bean
在基于 XML 或 Java Config 的老项目中,必须手动声明 PropertySourcesPlaceholderConfigurer Bean,否则 @Value 中的 ${} 不会被解析。
- XML 方式(推荐):
<context:property-placeholder location="classpath:db.properties,classpath:redis.properties" ignore-unresolvable="true" />
这行等价于注册一个PropertySourcesPlaceholderConfigurer,自动支持通配符(classpath*:)和多个文件 - Java Config 方式:
@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setLocations(
new ClassPathResource("db.properties"),
new ClassPathResource("redis.properties")
);
configurer.setIgnoreUnresolvablePlaceholders(true);
return configurer;
}
加载自定义 properties 文件:@PropertySource 是补充,不是替代
@PropertySource 的作用是将指定文件内容“注入”到 Spring 的 Environment 属性源中,但它本身不触发占位符解析 —— 解析仍依赖 PropertySourcesPlaceholderConfigurer。
立即学习“Java免费学习笔记(深入)”;
- 必须搭配
@Value或Environment.getProperty()使用 - 常见写法:
@Configuration
@PropertySource("classpath:weixin.properties")
public class WeixinConfig {
@Value("${appid}") private String appid;
} - 若文件路径错误且
ignoreResourceNotFound = false(默认),启动失败;设为true可静默忽略 - 支持 UTF-8 编码防乱码:
@PropertySource(value = "classpath:conf_zh.properties", encoding = "UTF-8")
高级控制:优先级、编码与容错
PropertySourcesPlaceholderConfigurer 提供细粒度控制,适用于复杂部署场景:
-
属性优先级:多个同名 key 出现在不同文件时,后注册的 source 覆盖先注册的(可通过
setOrder()显式排序) -
字符编码:中文属性易乱码,务必设置
fileEncoding = "UTF-8"(XML 中用file-encoding属性) -
容错开关:
ignoreUnresolvablePlaceholders = true允许存在未定义的占位符(不推荐生产环境开启) -
本地属性覆盖:可调用
setLocalProperties()注入硬编码 Properties,配合setLocalOverride(true)让本地值优先于外部文件


















