【死磕 Spring】----- IOC 之 PropertyPlaceholderConfigurer 的应用

原文:https://www.cmsblogs.com/category/1391374860344758272 『chenssy』


在博客 【死磕 Spring】----- IOC 之 深入分析 PropertyPlaceholderConfigurer 中了解了 PropertyPlaceholderConfigurer 内部实现原理,她允许我们在 XML 配置文件中使用占位符并将这些占位符所代表的资源单独配置到简单的 properties 文件中来加载。这个特性非常重要,因为它我们对 Bean 实例属性的配置变得非常容易控制了,主要使用场景有:

  1. 动态加载配置文件,多环境切换
  2. 属性加解密

下面我们就第一个应用场景来做说明。

利用 PropertyPlaceholderConfigurer 实现多环境切换

在我们项目开发过程中,都会存在多个环境,如 dev 、test 、prod 等等,各个环境的配置都会不一样,在传统的开发过程中我们都是在进行打包的时候进行人工干预,或者将配置文件放在系统外部,加载的时候指定加载目录,这种方式容易出错,那么有没有一种比较好的方式来解决这种情况呢?有,利用 PropertyPlaceholderConfigurer 的特性来动态加载配置文件,实现多环境切换

首先我们定义四个 Properties 文件,如下:

内容如下:

- application-dev.properties
student.name=chenssy-dev

- application-test.properties
student.name=chenssy-test

- application-prod.properties
student.name=chenssy-prod

然后实现一个类,该类继承 PropertyPlaceholderConfigurer,实现 loadProperties(),根据环境的不同加载不同的配置文件,如下:

public class CustomPropertyConfig extends PropertyPlaceholderConfigurer {

    private Resource[] locations;

    private PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();

    @Override
    public void setLocations(Resource[] locations) {
        this.locations = locations;
    }

    @Override
    public void setLocalOverride(boolean localOverride) {
        this.localOverride = localOverride;
    }

    /**
     * 覆盖这个方法,根据启动参数,动态读取配置文件
     * @param props
     * @throws IOException
     */
    @Override
    protected void loadProperties(Properties props) throws IOException {
        if (locations != null) {
            // locations 里面就已经包含了那三个定义的文件
            for (Resource location : this.locations) {
                InputStream is = null;
                try {
                    String filename = location.getFilename();
                    String env = "application-" + System.getProperty("spring.profiles.active", "dev") + ".properties";

                    // 找到我们需要的文件,加载
                    if (filename.contains(env)) {
                        logger.info("Loading properties file from " + location);
                        is = location.getInputStream();
                        this.propertiesPersister.load(props, is);

                    }
                } catch (IOException ex) {
                    logger.info("读取配置文件失败.....");
                    throw ex;
                } finally {
                    if (is != null) {
                        is.close();
                    }
                }
            }
        }
    }
}

配置文件:

    <bean id="PropertyPlaceholderConfigurer" class="org.springframework.core.custom.CustomPropertyConfig">
        <property name="locations">
            <list>
                <value>classpath:config/application-dev.properties</value>
                <value>classpath:config/application-test.properties</value>
                <value>classpath:config/application-prod.properties</value>
            </list>
        </property>
    </bean>

    <bean id="studentService" class="org.springframework.core.service.StudentService">
        <property name="name" value="${student.name}"/>
    </bean>

在 idea 的 VM options 里面增加 -Dspring.profiles.active=dev,标志当前环境为 dev 环境。测试代码如下:

ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

StudentService studentService = (StudentService) context.getBean("studentService");
System.out.println("student name:" + studentService.getName());

运行结果:

student name:chenssy-dev

当将 -Dspring.profiles.active 调整为 test,则打印结果则是 chenssy-test,这样就完全实现了根据不同的环境加载不同的配置,如果各位用过 Spring Boot 的话,这个就完全是 Spring Boot 里面的 profiles.active 。

PropertyPlaceholderConfigurer 对于属性的配置非常灵活,就看怎么玩了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大明哥_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值