PropertySource
类与 @PropertySource
注解详解与对比
在这里插入图片描述
一、PropertySource
类详解
1. 类型与作用
- 类型:接口(
org.springframework.core.env.PropertySource
) - 作用:抽象配置数据源,提供统一的键值对访问接口,是 Spring 环境配置(
Environment
)的基础。
2. 核心方法
public interface PropertySource<S> {String getName(); // 获取属性源名称(如 "systemEnvironment")Object getProperty(String name); // 获取属性值(返回 Object 类型)S getSource(); // 获取原始资源对象(如文件或系统环境变量)
}
3. 常见实现类
实现类 | 用途 |
---|---|
MapPropertySource | 将 Map 转换为属性源,用于内存中存储的键值对。 |
SystemEnvironmentPropertySource | 封装系统环境变量(如 JAVA_HOME 、PATH )。 |
PropertiesPropertySource | 加载 application.properties 或 *.properties 文件。 |
YamlPropertySource | 加载 application.yml 或 *.yml 文件。 |
4. 使用场景
- 底层实现:所有配置源(文件、环境变量、JNDI 等)均通过
PropertySource
接口统一管理。 - 扩展性:开发者可自定义实现,如动态内存配置。
二、@PropertySource
注解详解
1. 类型与作用
- 类型:注解(
org.springframework.context.annotation.PropertySource
) - 作用:声明需要加载的外部属性文件路径,扩展 Spring 的配置源。
2. 核心属性
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PropertySource {String[] value() default {}; // 配置文件路径(如 "classpath:custom.properties")String[] name() default {}; // 属性源名称(可选)String encoding() default ""; // 文件编码(如 "UTF-8")Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class; // 自定义工厂
}
3. 使用场景
- 声明式配置:在
@Configuration
类中声明额外的属性文件。 - 扩展配置源:加载非默认的配置文件(如
custom.properties
)。
4. 示例代码
@Configuration
@PropertySource(value = "classpath:custom.properties", encoding = "UTF-8")
public class AppConfig {@Value("${custom.key}")private String customValue;
}
三、核心区别对比
对比维度 | PropertySource | @PropertySource |
---|---|---|
类型 | 接口(Spring 核心环境模块) | 注解(Spring 配置注解模块) |
作用 | 抽象配置数据源,提供键值对访问接口。 | 声明需要加载的属性文件路径,扩展配置源。 |
实现方式 | 需实现接口或使用内置实现类(如 PropertiesPropertySource )。 | 通过注解标注配置类,由 Spring 自动加载文件并转换为 PropertySource 。 |
使用层级 | Spring 环境的基础组件,直接参与 Environment 的管理。 | 配置类的注解,用于声明性扩展配置源。 |
数据来源 | 支持所有类型(文件、环境变量、内存等)。 | 仅支持文件(需通过 factory 属性扩展)。 |
优先级控制 | 通过 Environment 的 PropertySources 集合的顺序控制优先级。 | 默认按加载顺序添加到 PropertySources ,可通过 @Order 调整。 |
扩展性 | 可自定义实现类,灵活度高。 | 通过 factory 属性指定工厂,间接支持自定义数据源。 |
四、关联性
-
生命周期流程
@PropertySource
注解在 Spring 启动时被处理,通过PropertySourcesPlaceholderConfigurer
或ConfigurationClassPostProcessor
加载指定的属性文件。- 加载后的文件会被转换为
PropertySource
对象(如PropertiesPropertySource
),并注册到Environment
的PropertySources
集合中。
-
示例流程
// 1. 使用 @PropertySource 声明配置文件 @Configuration @PropertySource("classpath:custom.properties") public class AppConfig {}// 2. Spring 内部处理: // - 读取 custom.properties 文件内容 // - 转换为 PropertiesPropertySource 实现类 // - 注册到 Environment 的 PropertySources 集合中
五、总结表格
特性 | PropertySource | @PropertySource |
---|---|---|
类型 | 接口(org.springframework.core.env ) | 注解(org.springframework.context.annotation ) |
核心作用 | 封装配置数据源,提供键值对访问接口。 | 声明需要加载的属性文件路径,扩展配置源。 |
使用场景 | 实现底层配置源(如文件、环境变量、内存等)。 | 在配置类中声明性加载外部属性文件。 |
数据来源 | 支持任意类型(文件、系统环境、JNDI 等)。 | 仅支持文件(需通过工厂扩展)。 |
优先级控制 | 通过 PropertySources 集合顺序控制。 | 默认按加载顺序添加,可通过 @Order 调整。 |
扩展性 | 高(可自定义实现类)。 | 中(通过 factory 属性间接扩展)。 |
关键代码示例
1. 自定义 PropertySource
实现
public class CustomPropertySource implements PropertySource<String> {private final Map<String, Object> properties = new HashMap<>();private final String name;public CustomPropertySource(String name) {this.name = name;properties.put("custom.key", "value");}@Overridepublic Object getProperty(String name) {return properties.get(name);}@Overridepublic String getName() {return this.name;}
}// 注册到 Environment
@Configuration
public class AppConfig {@Autowiredprivate Environment environment;@PostConstructpublic void init() {ConfigurableEnvironment env = (ConfigurableEnvironment) environment;env.getPropertySources().addFirst(new CustomPropertySource("customConfig"));}
}
2. 使用 @PropertySource
注解
@Configuration
@PropertySource(value = "classpath:custom.properties", encoding = "UTF-8")
public class AppConfig {@Value("${custom.key}")private String customValue;
}
总结
PropertySource
是 Spring 配置系统的底层接口,用于抽象所有配置数据源,开发者可通过其实现类或自定义实现扩展配置能力。@PropertySource
是声明式注解,简化了加载外部属性文件的流程,通过 Spring 的自动处理将其转换为PropertySource
对象。- 两者共同作用:
@PropertySource
通过声明路径触发配置文件加载,最终由PropertySource
接口统一管理,实现灵活的配置管理。