【架构基础】Spring中的PropertySourcesPlaceholderConfigurer介绍 (并非新知识,比较古老的一种使用方式)

目录

■前言

■核心作用

■工作原理

■具体使用

■重要特性与进阶

[■与现代 Spring Boot 的关系](#■与现代 Spring Boot 的关系)

■历史版本与替代品

■总结

■扩展


====

■前言

关于 Spring 终端 PropertySourcesPlaceholderConfigurer

一般用于Batch启动时,读取的配置的 BeanConfig的xml中。

程序框架升级后,使用这种方式读取配置文件。

虽然比较古老,但是之前的方式更加古老。。。

虽然古老,但是基于旧框架升级的实用性来说,还是比较适用的,

毕竟,使用这种方式,对于原有代码的修改量的影响是最小的。
(比如,对原有 【Batch0XX.properties】配置文件中, key value的读取)

=============

■核心作用

它是一个 BeanFactoryPostProcessor,主要功能是解析 Spring 配置文件(如 XML)和 Java 注解中的占位符 ${...},并用来自属性源(.properties 文件、系统环境变量等)的实际值来替换它们。

====================

■工作原理

  1. 读取属性源 : 它会加载一个或多个属性文件(如 jdbc.propertiesapplication.properties)。

  2. 介入 Bean 生命周期 : 作为 BeanFactoryPostProcessor,它在 Spring IoC 容器加载了所有 bean 的定义之后、但在创建任何 bean 实例之前执行。

  3. 解析占位符 : 遍历所有 bean 的定义,查找其中字符串属性值里包含的 ${property.key} 格式的占位符。

  4. 替换值 : 根据属性源中 property.key 对应的值,替换掉占位符。如果找不到,可以根据配置决定是报错还是使用默认值(如 ${key:defaultValue})。

=====================

■具体使用

假设你有一个 jdbc.properties 文件:

java 复制代码
jdbc.url=jdbc:mysql://localhost:3306/mydb
jdbc.username=root

1. 在传统 Spring XML 配置中的使用:

XML 复制代码
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:jdbc.properties</value>
            <value>classpath:application.properties</value>
        </list>
    </property>
    <!-- 可选:定义找不到属性时是否忽略,默认为 false(报错) -->
    <property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>

<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
</bean>

2. 在基于 Java 的配置中的使用:

java 复制代码
@Configuration
@PropertySource("classpath:jdbc.properties") // 使用 @PropertySource 注解
public class AppConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    public DataSource dataSource(
            @Value("${jdbc.url}") String url,
            @Value("${jdbc.username}") String username) {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl(url);
        dataSource.setUsername(username);
        return dataSource;
    }
}

注意 :这里 PropertySourcesPlaceholderConfigurer@Bean 方法必须是 static 的。这是因为它需要作为 BeanFactoryPostProcessor 尽早被实例化,以影响其他 bean 的注册过程。

======

■重要特性与进阶

  • 属性源优先级 : 从 Spring 3.1 开始,引入了 EnvironmentPropertySource 抽象。PropertySourcesPlaceholderConfigurer 会访问 Environment,而 Environment 中包含一个有序的 PropertySources 列表(例如:系统属性 > 系统环境变量 > 应用属性文件)。这意味着高优先级的属性会覆盖低优先级的属性。

  • 默认值 : 占位符支持指定默认值,格式为 ${key:defaultValue}

XML 复制代码
<property name="timeout" value="${connection.timeout:30}"/>
  • 嵌套解析 : 解析后的值如果仍然包含占位符,可以进一步解析(通过 setNestedPlaceholder 配置)。

======================

■与现代 Spring Boot 的关系

Spring Boot 中,你几乎不需要再显式配置 PropertySourcesPlaceholderConfigurer。这是因为:

  1. 自动配置 : Spring Boot 的 spring-boot-autoconfigure 已经自动为你配置好了它。

  2. 宽松的绑定: Boot 提供了更强大的属性绑定机制。

  3. 丰富的属性源 : Boot 按照预定义的顺序(如 命令行参数 > SPRING_APPLICATION_JSON > 系统属性 > OS环境变量 > application-{profile}.properties > application.properties 等)自动加载属性,优先级高的会覆盖低的。

  4. application.properties/yml: Boot 默认会从特定位置查找这些文件并加载其中的属性。

在 Spring Boot 应用中,你只需要:

  • application.yml 中定义属性:
XML 复制代码
app:
  service:
    endpoint: https://api.example.com

在代码中直接使用 @Value 注入:

java 复制代码
@Service
public class MyService {
    @Value("${app.service.endpoint}")
    private String endpoint;
    // ...
}
  • 或者使用类型安全的 @ConfigurationProperties 绑定。

=======================

■历史版本与替代品

  • PropertyPlaceholderConfigurer : 在 Spring 3.1 之前使用的旧类。PropertySourcesPlaceholderConfigurer 是其升级版,设计更优,能与新的 EnvironmentPropertySource API 集成。现在推荐使用新的

  • Spring 的 Environment API : 对于编程式访问属性,可以直接注入 org.springframework.core.env.Environment 对象。

java 复制代码
@Autowired
private Environment env;
String url = env.getProperty("jdbc.url");

====================

■总结

PropertySourcesPlaceholderConfigurer 是 Spring 框架中处理属性占位符 ${...} 替换的关键基础设施组件。

  • 做什么: 将配置文件中的占位符替换为实际值。

  • 何时执行: 在 bean 实例化之前。

  • 在传统 Spring 中: 需要显式配置。

  • 在 Spring Boot 中 : 已被自动配置,开发者无需操心,只需关注 application.properties/yml@Value@ConfigurationProperties 的使用即可。

如果你的配置占位符 ${} 没有生效,检查是否缺少了这个 bean 的配置(在非 Boot 项目中)或者属性文件是否正确加载,是首要的排查步骤。

=======================

■扩展

Servlet,Spring,Spring Boot,Sprint Batch,ThymeLeaf 学习_springbatch怎么启动-CSDN博客

====

相关推荐
_小马快跑_1 天前
Java 的 8 大基本数据类型:为何是不可或缺的设计?
java
爱勇宝1 天前
2026一人公司生存指南:用AI大模型,90天跑出你的第一条现金流
前端·后端·架构
偷油师傅1 天前
拆解 OpenClaw - 05:13 个省 Token 的设计
架构
兆子龙1 天前
当「多应用共享组件」成了刚需:我们从需求到模块联邦的落地小史
前端·架构
Re_zero1 天前
线上日志被清空?这段仅10行的 IO 代码里竟然藏着3个毒瘤
java·后端
洋洋技术笔记1 天前
Spring Boot条件注解详解
java·spring boot
sunny_2 天前
⚡️ vite-plugin-oxc:从 Babel 到 Oxc,我为 Vite 写了一个高性能编译插件
前端·webpack·架构
兆子龙2 天前
模块联邦(Module Federation)详解:从概念到手把手 Demo
前端·架构
程序员清风2 天前
程序员兼职必看:靠谱软件外包平台挑选指南与避坑清单!
java·后端·面试
Bigger2 天前
告别版本焦虑:如何为 Hugo 项目定制专属构建环境
前端·架构·go