zoukankan      html  css  js  c++  java
  • Spring中手动增加配置文件中占位符引用的变量

    在项目中遇到一个这样的需求,项目的配置文件由外部传入,这时spring配置文件那些占位符变量该如何取值呢?

    解决这个问题的做法有几种,我想到的大概有以下三种:

    1.通过系统属性来实现,把外部传入的配置信息保存到系统属性,spring配置中的占位符可以获取到系统属性的值.这种做法很简单,调用System.setProperty() | setProperties()方法就可以实现。

    2.把外部的配置信息动态写入到配置文件,生成配置文件之后再启动spring.spring的配置文件中需要把生成配置文件的配置写到PropertyPlaceholderConfigurerlocation属性。这种方式有点绕,还可以更优雅一点。

    3.我们知道spring配置文件中占位符替换是在PropertyPlaceholderConfigurer类中实现的,也就是说该类中必定维护了一种占位符变量与该值的Map数据结构(实际上是Properties,当然Properties本身就是基于Hashtable实现的),我们只需要找到该集合,spring加载完其他配置文件以后往这个集合中添加我们自定义的配置,也可以同样解决这个需求.并且个人觉得这个方式相比之前两种都有意思点。

    这篇文章我们主要讨论第三种实现方式,首先说解决办法,之后再简单说下这样的原因。解决办法就是自定义一个类,继承PropertyPlaceholderConfigurer,复写processProperties(),实际上该类是spring中的一个后处理器(BeanFactoryPostProcessor)

    import java.util.Map;
    import java.util.Properties;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
    /**
     * 扩展PropertyPlaceholderConfigurer类,不仅可以加载配置文件中的配置信息,还可以手动增加其他配置
     *    使用该类前,在spring配置文件中增加如下配置:
         <bean class=" com.xxx.aaa.context.ExternalPropertyResourceInjector">
             <!-- 如果还要加载module.properties文件中的配置信息,添加如下配置 -->
            <property name="locations">
                <list>
                    <value>classpath:module.properties</value>
                </list>
            </property>
        </bean>    
        注:该类是PropertyPlaceholderConfigurer的子类,如果配置了该类,无需在重复配置PropertyPlaceholderConfigurer
        
     * @see org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
     * @author Jack
     */
    public class ExternalPropertyResourceInjector extends PropertyPlaceholderConfigurer {
    
        @Override
        protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException {
            Map<String,String> map = new HashMap<String,String>();
    // map.put(key,value) ... 添加配置信息
            props.putAll(map);
            super.processProperties(beanFactory, props);
        }
    
    }

    配置bean:

    <bean class=" com.xxx.aaa.context.ExternalPropertyResourceInjector">
        <!-- 如果还要加载其他配置文件,配置locations属性即可
            <property name="locations">
                <list>
                    <value>classpath:module.properties</value>
                </list>
            </property>
         -->
    </bean>

    上面说了解决的办法,现在来看下解决该问题两个关键的地方,其一,在于弄清楚spring在哪个地方替换配置文件中所使用到占位符?第二个关键在于找到spring加载占位符中变量值配置文件之后保存配置的集合。这两个点都需要对照源码才能找到.

    这两个关键的地方都都可以从PropertyPlaceholderHelper可以入手.replacePlaceholders()方法处设置断点,debug模式下可以清晰看到占位符的替换过程。

    parseStringValue()方法中的147行可以看到占位符取值来源何处.

    从以上两点顺藤摸瓜就能找到spring加载配置文件并进行占位符替换的流程。

  • 相关阅读:
    oracle行转列
    JVM设置空间大小
    Spring AOP 业务权限管理
    清晨漫步
    pull解析xml(android)
    今昔何昔
    Spring: Document root element "beans", must match DOCTYPE root "null
    xfire
    心之所向
    Oracle数据库连接
  • 原文地址:https://www.cnblogs.com/heavenyes/p/4654460.html
Copyright © 2011-2022 走看看