`

Spring框架下资源属性的配置器类PropertyPlaceholderConfigurer

    博客分类:
  • java
阅读更多
   在applicationContext.xml里配置DBCP数据链接池时,dbcp.properties
dbcp.driverClassName = com.microsoft.sqlserver.jdbc.SQLServerDriver
dbcp.url = jdbc:sqlserver://192.168.1.132:1433;DatabaseName=HotelDB
dbcp.username = YXCK
dbcp.password = 123456
#连接池的最大数据库连接数,设为0表示无限制。 
dbcp.maxActive = 5
#数据库连接的最大空闲时间。超过此空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。
dbcp.maxIdle = 30
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。 
dbcp.maxWait = 10000
dbcp.defaultAutoCommit = true
#回收被遗弃的(一般是忘了释放的)数据库连接到连接池中。
dbcp.removeAbandoned = true
# 数据库连接过多长时间不用将被视为被遗弃而收回连接池中。
dbcp.removeAbandonedTimeout = 30
# 将被遗弃的数据库连接的回收记入日志。
dbcp.logAbandoned = true

applicationContext.xml配置
<!-- 定义数据源Bean,使用DBCP数据源实现 -->

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

<property name="driverClassName" value="${dbcp.driverClassName}" />  
    <property name="url" value="${dbcp.url}" />  
    <property name="username" value="${dbcp.username}" />  
    <property name="password" value="${dbcp.password}" />  
    <property name="maxActive" value="30"/><!--   value="${jdbc.maxActive}" />  -->
       <property name="maxIdle" value="${dbcp.maxIdle}" />  
       <property name="maxWait" value="${dbcp.maxWait}" />  
       <property name="defaultAutoCommit" value="${dbcp.defaultAutoCommit}"/>  
       <property name="removeAbandoned" value="${dbcp.removeAbandoned}"/>  
       <property name="removeAbandonedTimeout" value="${dbcp.removeAbandonedTimeout}"/>  
       <property name="logAbandoned" value="${dbcp.logAbandoned}"/>

</bean>以${}方式读取properties
文件里的配置,当为int类型时出现下面的错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.lang.String] to required type [int] for property 'maxActive'; nested exception is java.lang.NumberFormatException: For input string: "${jdbc.maxActive}"
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3830)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4337)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:516)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:566)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.lang.String] to required type [int] for property 'maxActive'; nested exception is java.lang.NumberFormatException: For input string: "${jdbc.maxActive}"
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:391)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1289)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1250)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
... 29 more
Caused by: java.lang.NumberFormatException: For input string: "${jdbc.maxActive}"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:447)
at java.lang.Integer.valueOf(Integer.java:553)
at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:157)
at org.springframework.beans.propertyeditors.CustomNumberEditor.setAsText(CustomNumberEditor.java:114)
at org.springframework.beans.TypeConverterDelegate.doConvertTextValue(TypeConverterDelegate.java:382)
at org.springframework.beans.TypeConverterDelegate.doConvertValue(TypeConverterDelegate.java:358)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:173)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:138)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:386)
... 33 more

  发现时不能正确读取int类型的原因,经过变化关键词“applicationContext文件以${}方式读取properties文件的信息”搜索到,在Spring - applicationContext.xml配置文件中读取properties配置文件的内容可以使用org.springframework.beans.factory.config.PropertyPlaceholderConfigurer类。哈哈,看到希望继续变化关键词“org.springframework.beans.factory.config.PropertyPlaceholderConfigurer”结果找到

http://thomaslee007.iteye.com/blog/167762
下面是其内容
Spring框架下PropertyPlaceholderConfigurer类
它的作用是一个资源属性的配置器,能够将BeanFactory的里定义的内容放在一个以.propertis后缀的文件中.



要了解这个类首先要弄清楚一个概念:bean factory post-processor
官方解释是这样的:
A bean factory post-processor is a java class which implements the
org.springframework.beans.factory.config.BeanFactoryPostProcessor interface. It is executed manually (in the case of the BeanFactory) or automatically (in the case of the ApplicationContext) to apply changes of some sort to an entire BeanFactory, after it has been constructed.
我理解的意思是这样的:
1.首先bean factory post-processor实现了org.springframework.beans.factory.config.BeanFactoryPostProcessor接口。
2.在BeanFactory的情况下它被手动的执行。
3.在ApplicationContext的条件下它会自动的执行。
4.最关键的一点是,是在一个类的实例被构造出来之后,对整个BeanFactory进行修改。

--------------------------------------------------------------------------------------------------------------------------------

Spring的框架中为您提供了一个 BeanFactoryPostProcessor 的实作类别: org.springframework.beans.factory.config.PropertyPlaceholderConfigurer。藉由这个类别,您可以将一些组态设定,移出至.properties档案中,如此的安排可以让XML定义档负责系统相关设定,而.properties档可以作为客户根据需求,自定义一些相关的参数。
来看一个Bean定义档的实际例子:

beans-config.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="configBean"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="location">
                <value>hello.properties</value>
            </property>
        </bean>

        <bean id="helloBean" class="onlyfun.caterpillar.HelloBean">
            <property name="helloWord">
                <value>${onlyfun.caterpillar.helloWord}</value>
            </property>
        </bean>
</beans>
假设在helloBean中有许多依赖注入的属性,这些都是比较不常变动的属性,而其中helloWord会经常变动,可以透过hello.properties来简单的设定,而这个资讯已设定在configBean的location属性中:

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

如果有多个.properties档案,则可以透过locations属性来设定,例如:

beans-config.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="configBean"
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>hello.properties</value>
                    <value>welcome.properties</value>
                    <value>other.properties</value>
   
                </list>
            </property>    
        </bean>

        <bean id="helloBean" class="onlyfun.caterpillar.HelloBean">
            <property name="helloWord">
                <value>${onlyfun.caterpillar.helloWord}</value>
            </property>
            ...
        </bean>
</beans> ======================================PropertyPlaceholderConfigurer类就是bean factory post-processor的一种,它的作用是一个资源属性的配置器,能够将BeanFactory的里定义的内容放在一个以.propertis后缀的文件中。
例如---spring-context.xml----
<bean id="propertyConfigurer"     class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
           <property name="locations">
               <list>
                   <value>/WEB-INF/jdbc.properties</value>
               </list>
           </property>
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName"><value>${driver}</value></property>
      <property name="url"><value>jdbc:${dbname}</value></property>
</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中就可以了
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-context.xml</param-value>
</context-param>
当然,不要忘了spring的监听器注册
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
这样,一个简单的数据源就设置完毕了。
实际上,PropertyPlaceholderConfigurer起的作用就是将占位符指向的数据库配置信息放在bean中定义
的工具。



这样真正的原因明白了,需要PropertyPlaceholderConfigurer类,在applicationContext.xml加上
<!-- 配置PropertyPlaceholderConfigurer,将占位符指向的数据库配置信息放在bean中定义 -->

<bean name="customName"     class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
             <property name="location">
                <value>/WEB-INF/dbcp.properties</value>
                        </property>

</bean>
问题解决。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics