@PropertySource 注解学习笔记
一、🔍 什么是 @PropertySource?
@PropertySource 是 Spring 框架提供的一个 注解,用于指定自定义的外部属性文件(如 .properties 或 .yml 文件),让 Spring 在启动时加载这些配置文件中的键值对,并能够通过 @Value 或 Environment 对象来访问这些属性。
⚠️ 注意:@PropertySource 默认只支持 .properties 文件,不支持直接加载 .yml / .yaml 文件(要加载 yml 需要额外配置或使用其他方式)。
二、📦 作用
- 加载自定义的 properties 配置文件
- 让配置文件中的属性能够被 Spring 容器管理
- 支持通过 @Value 注入 或 Environment 对象获取
- 通常与 @Configuration 类一起使用
三、🔧 基本语法
注解定义:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(PropertySources.class)
public @interface PropertySource {String[] value(); // 属性文件路径(必填)boolean ignoreResourceNotFound() default false; // 文件找不到时是否忽略String encoding() default ""; // 指定文件编码,如 UTF-8Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
}
四、📌 常用属性说明
属性 | 说明 | 默认值 | 是否必填 |
---|---|---|---|
value / name | 指定一个或多个 properties 文件路径(Classpath 下) | 无 | ✅ 必填 |
ignoreResourceNotFound | 如果配置文件不存在,是否忽略报错(不中断启动) | false | 否 |
encoding | 指定 properties 文件编码(如 UTF-8,解决中文乱码) | 空(默认系统编码) | 否 |
factory | 自定义 PropertySource 工厂(用于加载 yml 等非标准格式) | 默认工厂 | 否 |
value
和name
是等价的,都是用来指定配置文件路径- 可以同时加载多个文件:
@PropertySource({"file1.properties", "file2.properties"})
五、✅ 使用示例
1️⃣ 准备一个 properties 文件
在 src/main/resources
目录下创建一个配置文件,例如:
📄 application-custom.properties
app.name=MySpringApp
app.version=1.0.0
server.port=9090
user.name=Alice
user.age=25
2️⃣ 创建一个 @Configuration 类并使用 @PropertySource
📄 AppConfig.java
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;@Configuration
@PropertySource("classpath:application-custom.properties") // 加载自定义配置文件
public class AppConfig {// 这个类本身可以为空,只是用来引入配置文件
}
🔸
classpath:
表示该文件位于src/main/resources
目录下
🔸 你也可以使用相对路径,如"application-custom.properties"
(如果它在 classpath 根目录)
3️⃣ 使用 @Value 注入属性值
📄 SomeService.java
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;@Service
public class SomeService {@Value("${app.name}")private String appName;@Value("${app.version}")private String appVersion;@Value("${user.name}")private String userName;@Value("${user.age}")private int userAge;public void printConfig() {System.out.println("应用名称: " + appName);System.out.println("应用版本: " + appVersion);System.out.println("用户姓名: " + userName);System.out.println("用户年龄: " + userAge);}
}
运行后输出类似:
应用名称: MySpringApp
应用版本: 1.0.0
用户姓名: Alice
用户年龄: 25
4️⃣ 通过 Environment 对象获取属性(替代方案)
你也可以不用 @Value,而是注入 Environment 对象来获取值:
📄 SomeOtherService.java
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;@Service
public class SomeOtherService {private final Environment env;public SomeOtherService(Environment env) {this.env = env;}public void showConfig() {System.out.println("应用名: " + env.getProperty("app.name"));System.out.println("用户年龄: " + env.getProperty("user.age", "18")); // 默认值}
}
六、🔒 加载多个配置文件
你可以一次加载多个 properties 文件:
@PropertySource({"classpath:config1.properties","classpath:config2.properties"
})
七、⚠️ 常见问题与注意事项
❓ 1. @PropertySource 能加载 .yml 文件吗?
不可以!默认 @PropertySource 只支持 .properties 文件。
如果你想加载 YAML / YML 文件,需要借助第三方库,比如:
- spring-boot-configuration-processor
- 或者使用 @ConfigurationProperties(推荐用于 YAML)
- 或者自定义 PropertySourceFactory(高级用法)
🔧 推荐做法:YAML 文件一般放在 application.yml 中,结合 @ConfigurationProperties 使用,而不是用 @PropertySource
❓ 2. 文件找不到会报错吗?
默认情况下,如果指定的 properties 文件不存在,Spring 启动会报错。
✅ 解决方法:设置 ignoreResourceNotFound = true
@PropertySource(value = "classpath:optional-config.properties",ignoreResourceNotFound = true
)
这样即使文件不存在,程序也能正常启动,不会报错。
❓ 3. 如何指定文件编码(比如解决中文乱码)?
使用 encoding 属性:
@PropertySource(value = "classpath:messages_zh_CN.properties",encoding = "UTF-8"
)
❓ 4. @PropertySource 可以放在哪里?
通常放在一个 @Configuration 类上,例如:
@Configuration
@PropertySource("classpath:app.properties")
public class AppConfig {
}
也可以与 @ComponentScan, @Bean, @Import 等注解一起使用,它是 Spring 配置类的一部分。
八、📋 @PropertySource 与 @ConfigurationProperties 对比
特性 | @PropertySource + @Value | @ConfigurationProperties |
---|---|---|
加载文件类型 | 支持 .properties(推荐) | 支持 .properties / .yml(需配合 spring-boot) |
书写方式 | 通过 @Value 逐个注入 | 通过对象绑定(推荐批量管理配置) |
类型安全 | 弱(字符串形式注入) | 强(直接映射为对象属性) |
适用场景 | 少量配置、快速使用 | 大量相关配置、结构化、类型安全 |
注解位置 | @Configuration 类 | @Configuration 类 + @EnableConfigurationProperties |
✅ 推荐:如果你的配置项很多、有分组,建议使用 @ConfigurationProperties,更加结构化、类型安全!
九、🔖 小结:@PropertySource 语法速查
项目 | 语法 / 示例 |
---|---|
基本语法 | @PropertySource("classpath:xxx.properties") |
加载多个文件 | @PropertySource({"file1.properties", "file2.properties"}) |
忽略文件不存在 | ignoreResourceNotFound = true |
指定编码 | encoding = "UTF-8" |
与 @Value 配合 | @Value("${key}") |
与 Environment 配合 | env.getProperty("key") |
支持文件类型 | 仅 .properties(默认) |
YAML 支持 | 不支持(需用 @ConfigurationProperties) |
✅ 总结
问题 | 答案 |
---|---|
@PropertySource 是什么? | 用于加载自定义的 properties 配置文件的 Spring 注解 |
加载什么格式? | 主要支持 .properties 文件,默认不支持 .yml |
如何使用? | 加在 @Configuration 类上,指定文件路径,然后用 @Value 或 Environment 获取值 |
可以加载多个文件吗? | 可以:@PropertySource({ "a.properties", "b.properties" }) |
文件找不到会报错吗? | 默认会,可设置 ignoreResourceNotFound=true 避免 |
如何解决中文乱码? | 指定 encoding="UTF-8" |
YAML 文件怎么加载? | 不要用 @PropertySource,推荐用 @ConfigurationProperties |
📌 附加建议:
- 小项目、简单配置 → @PropertySource + @Value 足够
- 中大型项目、结构化配置 → 推荐使用 application.yml + @ConfigurationProperties
- 想深入了解 YAML 加载,可以学习 @EnableConfigurationProperties 和 @ConstructorBinding(Spring Boot 2.2+)
如你想要,我也可以为你整理一份 Markdown 或 PDF 版的 @PropertySource 笔记,或者进一步讲解 @ConfigurationProperties 的用法,欢迎继续提问 😊