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

目录

■前言

■核心作用

■工作原理

■具体使用

■重要特性与进阶

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

■历史版本与替代品

■总结

■扩展


====

■前言

关于 Spring 终端 PropertySourcesPlaceholderConfigurer

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

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

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

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

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

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

■核心作用

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

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

■工作原理

  1. 读取属性源 : 它会加载一个或多个属性文件(如 jdbc.properties、application.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 开始,引入了 Environment 和 PropertySource 抽象。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 是其升级版,设计更优,能与新的 Environment 和 PropertySource 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博客

====

相关推荐
xcl09253 小时前
北京24小时自助健身房系统软件开发实战:从架构到部署全流程指南
java·spring boot·架构
一 乐4 小时前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
卓怡学长5 小时前
w214基于jsp知道特产网
java·intellij-idea
步行cgn5 小时前
Spring 注解使用详解
java·spring
一条小小yu5 小时前
Spring IoC的理解
java·后端·spring
落魄实习生5 小时前
Agent Scope Java 2.x 系列【7】工具使用
java·开发语言·ai
旺仔学长 哈哈5 小时前
springboot钓鱼爱好者交流平台APP设计与实现
java·spring boot·mysql·充电桩管理系统
萧瑟余晖6 小时前
Dubbo SPI扩展机制详解
架构·dubbo
Shulex6 小时前
面向跨境电商多渠道消息系统的技术架构:亚马逊站内信合规对接与自动化执行链路设计
运维·架构·自动化