spring中的PropertyPlaceholderConfigurer作用、用法

Spring的框架中提供了一个 BeanFactoryPostProcessor 的实作类别: org.springframework.beans.factory.config.PropertyPlaceholderConfigurer。藉由这个类别,我们可以将一些组态设定,移出至.properties档案中,如此的安排可以让XML定义档负责系统相关设定,而.properties档可以作为客户根据需求,自定义一些相关的参数。 
来看一个Bean定义档的实际例子: 
beans-config.xml 
Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"   
  3.     "http://www.springframework.org/dtd/spring-beans.dtd">   
  4.   
  5. <beans>    
  6.       <bean id="configBean"   
  7.  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">           <property name="location">               
  8. <value>hello.properties</value>           
  9.      </property>       
  10. </bean>   
  11.   
  12.       <bean id="helloBean" class="onlyfun.caterpillar.HelloBean">   
  13.           <property name="helloWord">   
  14.               <value>${onlyfun.caterpillar.helloWord}</value>   
  15.           </property>   
  16.       </bean>  
  17. </beans>  


假设在helloBean中有许多依赖注入的属性,这些都是比较不常变动的属性,而其中helloWord会经常变动,可以透过hello.properties来简单的设定,而这个资讯已设定在configBean的location属性中: 
hello.properties 
Java代码   收藏代码
  1. onlyfun.caterpillar.helloWord=Welcome!  


在helloBean的helloWord属性中,${onlyfun.caterpillar.helloWord}将会被hello.properties的helloWord所取代。 

如果有多个.properties档案,则可以透过locations属性来设定,例如: 
beans-config.xml 
Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"   
  3.     "http://www.springframework.org/dtd/spring-beans.dtd">   
  4.   
  5. <beans>    
  6.       <bean id="configBean"   
  7.     class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">           <property name="locations">   
  8.               <list>                  <value>hello.properties</value>   
  9.                   <value>welcome.properties</value>   
  10.                   <value>other.properties</value>       
  11.               </list>  
  12.           </property>           </bean>   
  13.   
  14.       <bean id="helloBean" class="onlyfun.caterpillar.HelloBean">   
  15.           <property name="helloWord">   
  16.               <value>${onlyfun.caterpillar.helloWord}</value>   
  17.           </property>   
  18.           ...  
  19.       </bean>  
  20. </beans>  

PropertyPlaceholderConfigurer类就是bean factory post-processor的一种,它的作用是一个资源属性的配置器,能够将BeanFactory的里定义的内容放在一个以.propertis后缀的文件中。 
例如---spring-context.xml---- 
Xml代码   收藏代码
  1. <bean id="propertyConfigurer"   class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  2.          <property name="locations">  
  3.              <list>  
  4.                  <value>/WEB-INF/jdbc.properties</value>  
  5.              </list>  
  6.          </property>  
  7.  </bean>  
  8. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
  9.     <property name="driverClassName"><value>${driver}</value></property>  
  10.     <property name="url"><value>jdbc:${dbname}</value></property>  
  11. </bean>  

而实际的jdbc.propertis文件是 
jdbc.driverClassName=org.hsqldb.jdbcDriver 
jdbc.url=jdbc:hsqldb:hsql://production:9002 
jdbc.username=sa 
jdbc.password=root 
而jdbc.propertis是怎样引用的呢: 将上边一段配置注册在web.xml中就可以了 
Xml代码   收藏代码
  1. <context-param>  
  2. <param-name>contextConfigLocation</param-name>  
  3. <param-value>/WEB-INF/spring-context.xml</param-value>  
  4. </context-param> 当然,不要忘了spring的监听器注册  
  5. <listener>  
  6. <listener-class>  
  7. org.springframework.web.context.ContextLoaderListener  
  8. </listener-class>  
  9. </listener>  

这样,一个简单的数据源就设置完毕了。 
实际上,PropertyPlaceholderConfigurer起的作用就是将占位符指向的数据库配置信息放在bean中定义 

的工具。 


1、一个简单的Demo

1.1、创建conf.xml

<?xml version= "1.0" encoding= "UTF-8"?>
<!DOCTYPE beans PUBLIC  "-//SPRING//DTD BEAN//EN"  "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean id= "propertyConfigurer"   class= "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <!-- 
        使用location属性定义单个配置文件
        <property name= "location">
            <value>classpath:/com/zsw/config/jdbc.properties</value>
        </property>
         -->
  
  <!-- 使用locations属性定义多个配置文件 -->
  <property name= "locations">
     <list>
        <value>classpath:/com/zsw/config/jdbc.properties</value>
     </list>
  </property> 
    </bean>
    <bean id= "dataSource"   class= "org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name= "url">
            <value>${database.url}</value>
        </property>
        <property name= "driverClassName">
            <value>${database.driver}</value>
        </property>
        <property name= "username">
            <value>${database.user}</value>
        </property>
        <property name= "password">
            <value>${database.password}</value>
        </property>
    </bean>
</beans>

1.2.创建jdbc.properties文件

database.driver=com.mysql.jdbc.Driver
database.url=jdbc:mysql: //localhost:3306/right?useUnicode=true&autoReconnect=true&characterEncoding=UTF-8
database.user=root
database.password=root
jdbc.pool.c3p0.acquire_increment=2
jdbc.pool.c3p0.max_size=20
jdbc.pool.c3p0.min_size=2
jdbc.pool.c3p0.preferred_test_query='SELECT 1'
jdbc.pool.c3p0.idle_connection_test_period=18000
jdbc.pool.c3p0.max_idle_time=25000

1.3.创建Config.java

package com.zsw.config;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.FileSystemResource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

public  class Config {
      public  static  void main( String[] args) {
         XmlBeanFactory factory =  new XmlBeanFactory( new FileSystemResource( "src/com/zsw/config/conf.xml"));
          // 如果要在BeanFactory中使用,bean factory post-processor必须手动运行:
         PropertyPlaceholderConfigurer cfg =  new PropertyPlaceholderConfigurer();
         cfg.setLocation( new FileSystemResource( "src/com/zsw/config/jdbc.properties"));
         cfg.postProcessBeanFactory(factory);
         DriverManagerDataSource dataSource = (DriverManagerDataSource) factory.getBean( "dataSource");
//         System.out.println(dataSource.getDriverClassName());
         
         
         System.out.println(dataSource.getUsername());
          // 注意,ApplicationContext能够自动辨认和应用在其上部署的实现了BeanFactoryPostProcessor的bean。这就意味着,当使用ApplicationContext的时候应用PropertyPlaceholderConfigurer会非常的方便。由于这个原因,建议想要使用这个或者其他bean
          // factory postprocessor的用户使用ApplicationContext代替BeanFactroy。
         ApplicationContext context =  new ClassPathXmlApplicationContext( "com/zsw/config/conf.xml");
         DriverManagerDataSource dataSource2 = (DriverManagerDataSource) context.getBean( "dataSource");
         System.out.println(dataSource2.getUsername());
     }
 
}

 

2.Spring中PropertyPlaceholderConfigurer多种配置方式

2.1配置单个Properties文件

< bean id= "propertyConfigurerForAnalysis"  class= "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
    < property name= "location" >
        < value>classpath:/spring/include/dbQuery.properties< /value>
    < /property>
< /bean>

其中classpath是引用src目录下的文件写法。

2.2 当存在多个Properties文件时,配置就需使用locations了:

  
  
< bean id= "propertyConfigurer"  class= "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >     < property name= "locations" >        < list>           < value>classpath:/spring/include/jdbc-parms.properties< /value>           < value>classpath:/spring/include/base-config.properties< /value>         < /list>     < /property> < /bean>

 

2.3、接下来我们要使用多个PropertyPlaceholderConfigurer来分散配置,达到整合多工程下的多个分散的Properties 文件,其配置如下:

<bean id= "propertyConfigurerForProject1"  class= "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name= "order" value= "1" />
    <property name= "ignoreUnresolvablePlaceholders" value= "true" />
    <property name= "location">
       <value>classpath:/spring/include/dbQuery.properties</value>
    </property>
</bean>

 

< bean id= "propertyConfigurerForProject2"  class= "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
    < property name= "order"  value= "2"  />
    < property name= "ignoreUnresolvablePlaceholders"  value= "true"  />
    < property name= "locations" >
      < list>
        < value>classpath:/spring/include/jdbc-parms.properties< /value>
        < value>classpath:/spring/include/base-config.properties< /value>
      < /list>
    < /property>
< /bean>

 

其中order属性代表其加载顺序,而ignoreUnresolvablePlaceholders为是否忽略不可解析的 Placeholder,如配置了多个PropertyPlaceholderConfigurer,则需设置为true


2,将property配置文件与工程分离(独立到服务器中)

   为什么想到要这样做呢?

   这是在实际开发部署中,每次将工程打包部署到服务器,都需要在服务器端修改工程的配置项(如数据源等),感觉很麻烦。

   如果工程优先读取放置在服务器上的配置文件,没有此配置文件才从工程目录里面读取,那样就可以将只在服务器存放一份配置文件并修改成与服务器运行环境一致,今后部署即可不用每次都修改工程配置文件了。

2.1 做法:

  刚才我们在第1点添加了一个propertyConfigurer,现将其改名为“propertyConfigurer2”,并添加一个“propertyConfigurer1”,两者配置为:

 

Xml代码   收藏代码
  1. <bean id="propertyConfigurer1"    
  2.           class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  3.         <property name="order" value="1"/>  
  4.          <property name="ignoreResourceNotFound" value="true"/>  
  5.         <property name="ignoreUnresolvablePlaceholders" value="true" />  
  6.         <property name="location" value="file:C:/tempSys/config/global-config-file.properties"/>    
  7.     </bean>   
  8.   
  9.     <bean id="propertyConfigurer2"    
  10.           class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">    
  11.         <property name="order" value="2"/>  
  12.         <property name="ignoreUnresolvablePlaceholders" value="true" />  
  13.         <property name="location" value="classpath:global-config-file.properties"/>    
  14.     </bean>   

 order属性表示加载顺序,这种配置表示先加载propertyConfigurer1,在加载propertyConfigurer2,两者配置文件中有同样的参数,后加载的参数不会覆盖先加载的。

 

  propertyConfigurer1需要添加一个 <property name="ignoreResourceNotFound" value="true"/>属性,表示当找不到这个配置文件时,则跳过,这样就不会抛出FileNotFoundException了。

  这样配置之后,工程会在启动时,首先检查C:/tempSys/config/global-config-file.properties是否存在,如果存在则加载器配置,随后再加载项目目录下的global-config-file.properties;如果不存在,则直接加载项目目录下的global-config-file.properties。

   

   这样做不单可将配置与开发环境分离出来,避免每次部署时繁琐的配置修改工作。同时这也提高了系统部署时的安全性,比如,实际运行的正式数据库账户密码信息将是十分机密的信息,由运维人员保管维护,可能对开发人员都不能公开(开发人员只知道开发测试数据库的信息),将这些信息直接配置在服务器上,服务器也由运维人员进行管理,这样可以减少机密信息的知晓人群,提高安全性。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值