spring使用PropertyPlaceholderConfigurer扩展来满足不同环境的参数配置

来源:互联网 发布:mac如何解压exe文件 编辑:程序博客网 时间:2024/05/20 09:11

spring使用PropertyPlaceholderConfigurer扩展来满足不同环境的参数配置,

来自:http://www.javaarch.net/jiagoushi/548.htm


PropertyPlaceholderConfigurer是spring提供我们来把一些环境变量(数据库连接相关参数,文件路径等)统一管理起来,然后在bean中指定对应的变量的。但是往往开发环境,测试环境,生成环境的这些参数配置是不同的,那么我们如何使用PropertyPlaceholderConfigurer扩展来满足不同环境的配置需求,而不需要在不同环境需要修改代码或者配置。


1.我们扩展下PropertyPlaceholderConfigurer,可以通过在properties中production.mode默认配置来或者不同环境的配置,然后有限通过取系统环境变量的这个值来作为我们开发环境,测试环境,生产环境的选择。

[java] view plain copy
  1. import java.io.IOException;  
  2. import java.util.Map.Entry;  
  3. import java.util.Properties;  
  4. import java.util.Set;  
  5.   
  6. import org.apache.commons.lang.StringUtils;  
  7. import org.springframework.beans.factory.InitializingBean;  
  8. import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;  
  9. /** 
  10.  * 可以按照不同的运行模式启用相应的配置 
  11.  *  
  12.  */  
  13. public class MutilPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer implements InitializingBean {  
  14.       
  15.     private static final String PRODUCTION_MODE = "production.mode";  
  16.     // 缓存所有的属性配置  
  17.     private Properties          properties;  
  18.     /** 
  19.      * @return the mode 
  20.      */  
  21.     public String getMode() {  
  22.         return properties.getProperty(PRODUCTION_MODE);  
  23.     }  
  24.     @Override  
  25.     protected Properties mergeProperties() throws IOException {  
  26.         Properties mergeProperties = super.mergeProperties();  
  27.         // 根据路由原则,提取最终生效的properties  
  28.         this.properties = new Properties();  
  29.         // 获取路由规则,系统属性设置mode优先  
  30.         String mode = System.getProperty(PRODUCTION_MODE);  
  31.         if (StringUtils.isEmpty(mode)) {  
  32.             String str = mergeProperties.getProperty(PRODUCTION_MODE);  
  33.             mode = str != null ? str : "ONLINE";  
  34.         }  
  35.         properties.put(PRODUCTION_MODE, mode);  
  36.         String[] modes = mode.split(",");  
  37.         Set<Entry<Object, Object>> es = mergeProperties.entrySet();  
  38.         for (Entry<Object, Object> entry : es) {  
  39.             String key = (String) entry.getKey();  
  40.             int idx = key.lastIndexOf('_');  
  41.             String realKey = idx == -1 ? key : key.substring(0, idx);  
  42.             if (!properties.containsKey(realKey)) {  
  43.                 Object value = null;  
  44.                 for (String md : modes) {  
  45.                     value = mergeProperties.get(realKey + "_" + md);  
  46.                     if (value != null) {  
  47.                         properties.put(realKey, value);  
  48.                         break;  
  49.                     }  
  50.                 }  
  51.                 if (value == null) {  
  52.                     value = mergeProperties.get(realKey);  
  53.                     if (value != null) {  
  54.                         properties.put(realKey, value);  
  55.                     } else {  
  56.                         throw new RuntimeException("impossible empty property for " + realKey);  
  57.                     }  
  58.                 }  
  59.             }  
  60.         }  
  61.         return properties;  
  62.     }  
  63.     /** 
  64.      * 开放此方法给需要的业务 
  65.      *  
  66.      * @param key 
  67.      * @return 
  68.      */  
  69.     public String getProperty(String key) {  
  70.         return resolvePlaceholder(key, properties);  
  71.     }  
  72.     @Override  
  73.     public void afterPropertiesSet() throws Exception {  
  74.         // TODO Auto-generated method stub    
  75.     }  
  76. }  
 

[java] view plain copy
  1. 然后我们在properties中可以这么配置:也就是默认配置是ONLINE 生产模式,那么只要在系统变量中没有配置production.mode,则我们取ONLINE的配置,也就是下面的参数取后缀为_ONLINE的配置。  
 
[java] view plain copy
  1. production.mode=ONLINE  
  2.   
  3.   
  4. #lucene index data dir  
  5. lucene.index.dir_DEV=e:\\logs\\lucene  
  6. lucene.index.dir_ONLINE=/home/admin/data  
  7.   
  8. #velocity  
  9. file.resource.loader.cache_DEV=false  
  10. file.resource.loader.modificationCheckInterval_DEV=2  
  11. file.resource.loader.cache_ONLINE=true  
  12. file.resource.loader.modificationCheckInterval_ONLINE=-1  
 对应spring的配置为:

[java] view plain copy
  1. <!-- velocity -->  
  2. <import resource="classpath*:*.xml" />  
  3. <bean id="velocityConfigurer"  
  4.     class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">  
  5.     <property name="resourceLoaderPath">  
  6.         <value>WEB-INF/velocity/</value>  
  7.     </property>  
  8.     <property name="velocityProperties">  
  9.         <props>  
  10.             <prop key="directive.foreach.counter.name">velocityCount</prop>  
  11.             <prop key="directive.foreach.counter.initial.value">1</prop>  
  12.             <prop key="input.encoding">GBK</prop>  
  13.             <prop key="output.encoding">GBK</prop>  
  14.             <prop key="file.resource.loader.cache">${file.resource.loader.cache}</prop>  
  15.             <prop key="file.resource.loader.modificationCheckInterval">${file.resource.loader.modificationCheckInterval}</prop>  
  16.             <prop key="velocimacro.library.autoreload">false</prop>  
  17.             <prop key="velocimacro.library">macro.vm</prop>  
  18.         </props>  
  19.     </property>  
  20. </bean>  
 

这种参数包括数据库连接串,文件路径等都可以这么配,因为velocity在测试环境不需要cache,能够修改即生效,但是线上环境加上cache则能提高性能,所以,默认使用ONLINE的配置,但是在测试环境的VM参数中加上-Dproduction.mode=DEV,则在开发环境用的是_DEV后缀的配置,到了线上代码则不用改。非常方便。

最好就是架上placeholder的自定义配置bean

[java] view plain copy
  1. <bean id="placeholder"  
  2.     class="org.springweb.core.MutilPropertyPlaceholderConfigurer">  
  3.     <property name="locations">  
  4.         <list>  
  5.             <value>classpath:jdbc.properties</value>  
  6.             <value>classpath*:*-placeholder.properties</value>  
  7.         </list>  
  8.     </property>  
  9. </bean>  
 
0 0
原创粉丝点击