Property-placeholder详解

一、property-placeholderhelp

Property-placeholder是Spring框架提供的一种用于替换XML中属性占位符的机制。它可以读取Properties文件,并且在XML文件中取出相应的属性值,并将其替换为占位符,该机制对于模块化配置、测试、灵活性以及重用方面都具有很大的优势。

在Spring的应用上下文中,通过PropertyPlaceholderConfigurer可以很方便的读取Properties文件,并用${}的语法来引用读取的属性值,当然在引用值为空的时候,可以设置默认值。例如:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>

在上述的代码中,${jdbc.driverClassName}、${jdbc.url}、${jdbc.username} 和 ${jdbc.password} 都是PropertyPlaceholderConfigurer读取Properties文件中所定义的属性名。

二、property-placeholderhelper

除了通过PropertyPlaceholderConfigurer来读取Properties文件之外,Spring 4.3版本以后,还提供了一个更加强大的属性加载机制 — PropertySourcesPlaceholderConfigurer。PropertySourcesPlaceholderConfigurer继承自PropertyPlaceholderConfigurer,并且更加灵活,支持从多个地方读取属性文件,包括系统属性、Java配置类、环境变量等等。实际上,它也是Spring @PropertySources注解使用的核心类。

在Java配置类中配置示例:

@Configuration
@ComponentScan
@PropertySources(value = {
        @PropertySource("classpath:application.properties"),
        @PropertySource("file:/opt/config/application.properties")
})
public class AppConfig {

    @Autowired
    Environment env;

    @Bean
    public DataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
        dataSource.setUrl(env.getProperty("jdbc.url"));
        dataSource.setUsername(env.getProperty("jdbc.username"));
        dataSource.setPassword(env.getProperty("jdbc.password"));
        return dataSource;
    }

}

使用PropertySourcesPlaceholderConfigurer可以在Java配置类中从多个地方加载属性,并且与其他的Spring组件无缝集成。

三、property-placeholder热加载

在大多数情况下,我们不会在运行时更改属性文件中的值,但是,在一些特殊的情况下,我们可能需要热修改Properties文件的值,并且更新Spring容器中的Bean。Spring框架自身并没有提供热修改属性文件的功能,但是我们可以自己实现一个热加载的机制。

我们可以在程序中监控Properties文件的修改,并且在文件发生变更时,重新读取Properties文件,并且更新Spring中的Bean。示例代码如下:

@Configuration
@PropertySources(value = {@PropertySource("classpath:config.properties")})
public class AppConfig {

    @Autowired
    Environment env;

    @Bean
    public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        configurer.setLocation(new ClassPathResource("config.properties"));
        configurer.setIgnoreResourceNotFound(false);
        configurer.setIgnoreUnresolvablePlaceholders(false);
        configurer.setProperties(CommonUtils.loadProperties(configurer.getLocation()));
        return configurer;
    }

    /**
     * 监听文件修改
     */
    @PostConstruct
    public void init() {
        String location = env.getProperty("spring.config.location");
        if (location != null) {
            File file = new File(location);
            if (!file.exists()) {
                throw new FileNotFoundException("The config file does not exist: " + file.toString());
            }
            if (location.endsWith(".properties")) {
                new PropertiesFileListener(file, this::reloadProperties).watch();
            }
        }
    }

    /**
     * 重新加载Properties文件
     * @param properties Properties
     */
    public void reloadProperties(Properties properties) {
        PropertySourcesPlaceholderConfigurer configurer = propertySourcesPlaceholderConfigurer();
        configurer.setProperties(properties);
    }

    ..........
}

四、PropertyPlaceholderConfigurer

PropertyPlaceholderConfigurer是Spring框架中的一个核心组件,它是Properties文件中的属性值占位符解析器。它提供了多种方式来解析Properties文件中的占位符,例如,可以使用系统环境变量、标准JRE属性、命令行参数、JNDI等等方式。通过PropertyPlaceholderConfigurer,我们可以轻松地将XML配置文件和Properties文件进行解耦合,从而实现灵活性和可维护性。例如:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:config.properties</value>
        </list>
    </property>
</bean>

在上述代码中,我们将Properties文件的配置放置到了Spring的Application Context对象中,并且可以通过占位符来引用Properties文件中的参数。

五、结合注解使用

除了XML配置之外,Property-placeholder在注解中也得到了广泛的应用,Spring提供了@Value注解来读取Properties文件中的配置参数,用法如下:

@Value("${jdbc.driverClassName}")
private String driverClassName;

@Value("${jdbc.url}")
private String url;

@Value("${jdbc.username}")
private String username;

@Value("${jdbc.password}")
private String password;

使用@Value注解读取Properties文件中的配置参数,可以避免在Java代码中硬编码参数值,也可以让配置从不同的环境中进行分离。

总结

Property-placeholder机制在Spring框架中得到了广泛地应用,在不同的开发场景中起到了不可替代的作用。通过本文的介绍,我们知道,Spring提供了多种加载Properties文件的方式,从XML配置、Java配置到注解方式,我们可以根据实际的开发情况来选择使用哪种方式。同时,在热加载方面,我们需要根据实际需求进行调整,以达到最佳的实践效果。

原创文章,作者:QMRW,如若转载,请注明出处:https://www.506064.com/n/138678.html

(0)
QMRWQMRW
上一篇 2024-10-04
下一篇 2024-10-04

相关推荐

  • 包含python中db2的使用的词条

    本文目录一览: 1、请教python在读取DB2时,显示中文问题 2、python 怎么连接db2数据库 3、db2索引怎么用? 请教python在读取DB2时,显示中文问题 感谢…

  • c语言编程166,一百以内素数C语言编程

    本文目录一览: 1、c语言问题求解 2、C语言程序设计课程讲什么内容? 3、c语言的问题 tk166填空 4、一个c语言的问题,我看了好长时间都看不懂,结果是(1)166(2)26…

    编程 2024-10-04
  • Python sum函数实现列表求和操作

    一、sum函数概述 Python是一种解释型高级编程语言,具有简单易学、可读性高、功能强大等特点。在Python中,很多操作都可以使用内置函数实现。而求列表(list)的和就可以使…

    编程 2024-10-04
  • java线程学习案例(java线程总结)

    本文目录一览: 1、java常用的几种线程池实例讲解 2、一个简单java多线程的示例 3、JAVA多线程 编程题两个案例,不会写,求大神写出代码,万分感谢,多线程还没学。 jav…

    编程 2024-10-04
  • 数据库及mysql概述(mysql数据库是什么数据库)

    本文目录一览: 1、MySQL数据库的简介 2、什么是MySql数据库 3、什么是mysql? 4、什么是mysql数据库? MySQL数据库的简介 MySQL是一种开放源代码的关…

    编程 2024-10-09
  • Python 程序:从元组中移除项目

    编写一个 Python 程序,从元组中移除或删除一个项目。在 Python 中,我们不能从元组中删除一个项目。相反,我们必须将其分配给一个新的元组。在这个例子中,我们使用元组切片和…

    编程 2024-10-03
  • C++Things——让你的C++编程更加高效

    一、C++Things简介 C++Things是一个用于C++开发的开源库,提供了一系列在C++编程中常用的工具和函数,可帮助开发人员快速开发高效、可靠、安全、易于维护的代码。C+…

    编程 2024-10-04
  • 对c语言一点不懂,为什么学了c语言还是看不懂

    本文目录一览: 1、C语言看不懂 2、C语言学不会怎么办? 3、c语言一点不懂,编程时也不知道怎么写 4、对c语言一窍不通……怎么学?从哪里开始? 5、C语言看不懂怎么办啊 C语言…

    编程 2024-10-08
  • Java实现文件复制

    一、文件复制的概念和应用 文件复制是一种常见而重要的文件处理操作,它能够在计算机系统中实现文件的备份、转移、共享等多种应用场景,同时也为解决数据安全问题、提升系统性能等方面做出重要…

    编程 2024-10-04
  • js运行lua,js运行时与编译时

    本文目录一览: 1、javascript和LUA这两个脚本语言哪个强一些? 2、jsmpeg.js如何动态更新配置项 3、有什么能将js代码转成lua代码的工具吗 4、lua怎么调…

    编程 2024-10-04

发表回复

登录后才能评论