【架构基础】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博客

====

相关推荐
chilavert3187 小时前
技术演进中的开发沉思-356:重排序(中)
java·开发语言
毕设源码-邱学长7 小时前
【开题答辩全过程】以 基于SSM的儿童福利院管理系统为例,包含答辩的问题和答案
java·eclipse
TT哇7 小时前
【实习】数字营销系统 银行经理端(interact_bank)前端 Vue 移动端页面的 UI 重构与优化
java·前端·vue.js·ui
静听松涛1337 小时前
大语言模型长上下文技术突破:如何处理超长文本的注意力机制与架构图解
人工智能·语言模型·架构
YaHuiLiang8 小时前
小微互联网公司与互联网创业公司-AI编程需要理性看待
架构
Elieal8 小时前
SpringBoot 数据层开发与企业信息管理系统实战
java·spring boot·后端
识君啊8 小时前
MyBatis-Plus 逻辑删除导致唯一索引冲突的解决方案
java·spring boot·mybatis·mybatis-plus·唯一索引·逻辑删除
Coder_Boy_8 小时前
Java开发者破局指南:跳出内卷,借AI赋能,搭建系统化知识体系
java·开发语言·人工智能·spring boot·后端·spring
QT.qtqtqtqtqt8 小时前
SQL注入漏洞
java·服务器·sql·安全