简体   繁体   English

PropertyPlaceholderConfigurer,用于读取属性文件和数据库

[英]PropertyPlaceholderConfigurer for reading property files and database

I am trying to create two PropertyPlaceholderConfigurer's, one for accessing property files and the other for accessing the database... the code is as follows 我正在尝试创建两个PropertyPlaceholderConfigurer,一个用于访问属性文件,另一个用于访问数据库。代码如下

  <bean id="otherPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="ignoreUnresolvablePlaceholders" value="true"/>
        <property name="properties">
        <bean class="org.apache.commons.configuration.ConfigurationConverter" factory-method="getProperties">
            <constructor-arg>
                <bean class="org.apache.commons.configuration.DatabaseConfiguration">
                    <constructor-arg ref="myDataSource"/>
                     <constructor-arg value="dbo.APPLICATIONPROPERTIES"/>
                     <constructor-arg value="NAME"/>
                   <constructor-arg value="VALUE"/>
                </bean>
            </constructor-arg>
        </bean>
        </property>
    </bean>

  <bean id="propertyConfigurer" class="com.fexco.wuams.util.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:database.properties</value>
            </list>         
        </property>
    </bean>

I have the following ComboPooledDataSource bean 我有以下ComboPooledDataSource bean

<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${driver}"/>
    <property name="jdbcUrl" value="${url}"/>
    <property name="user" value="${username}"/>
    <property name="password" value="${password}"/>
    <property name="initialPoolSize" value="5"/>
    <property name="minPoolSize" value="5"/>
    <property name="maxPoolSize" value="5"/>
    <property name="maxIdleTime" value="1200"/>
    <property name="idleConnectionTestPeriod" value="300"/>
  </bean>

which works perfectly for the rest of my application except when i try use it for my bean id="otherPropertyConfigurer" ... i get the following error 这对我的应用程序的其余部分完美地工作,除了当我尝试将其用于我的bean id="otherPropertyConfigurer" ...我收到以下错误

Caused by: org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'driverClass' threw exception; nested exception is java.beans.PropertyVetoException: Could not locate driver class with name '${jdbc.driverClassName}'.
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:104)
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:59)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1275)
    ... 72 more

if i hardcode the database variables in ComboPooledDataSource (eg change ${jdbc.driverClassName} to net.sourceforge.jtds.jdbc.Driver everything works fine but for some reason when i add the otherPropertyConfigurer , my original propertyConfigurer does not work 如果我将ComboPooledDataSource的数据库变量硬编码(例如,将${jdbc.driverClassName}更改${jdbc.driverClassName}net.sourceforge.jtds.jdbc.Driver一切正常,但是由于某些原因,当我添加otherPropertyConfigurer ,我原来的propertyConfigurer无法正常工作

Does anyone have any ideas on how to resolve this? 有人对如何解决这个问题有任何想法吗?

I hate to be the barer of bad news, but what you are trying to achieve, Spring physically can not do. 我讨厌成为坏消息的交换者,但是您要实现的目标,Spring在物理上是无法做到的。

Because Springs PropertyPlaceholderConfigurer classes as beanPostProcessors, it creates and invokes these beans before the creation of any other beans. 因为Springs PropertyPlaceholderConfigurer类作为beanPostProcessors类,所以它会在创建任何其他bean之前创建并调用这些bean。 However, if you have multiple PropertyPlaceholderConfigurer's, where one depends on another, Spring will always create both instances fully before invoking either of them. 但是,如果您有多个PropertyPlaceholderConfigurer,而一个依赖另一个,则Spring总是在调用两个实例之前完全创建两个实例。 Therefore your placeholders in myDataSource can never be resolved. 因此,您在myDataSource中的占位符将永远无法解析。

The problem is better described in this question . 这个问题可以更好地描述这个问题

The best solution to this problem is generally to stop using a database for your configuration management. 解决此问题的最佳方法通常是停止使用数据库进行配置管理。 I find that it is better to use a simple configuration file, which can be modified per environment, and hosted in your deployment container. 我发现最好使用一个简单的配置文件,该文件可以根据环境进行修改,并托管在您的部署容器中。

As ConMan suggested this cannot be done in the way that i was explaining in my question above. 正如ConMan所建议的那样,这不能以我在上面的问题中解释的方式来完成。 But i have managed to resolve this issue my instead passing the properties ( propertiesFromDB ) into the class using the following code 但是我设法解决了这个问题,我改为使用以下代码将属性( propertiesFromDB )传递给类

<bean id="propertiesFromDB"
        class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="properties" ref="configurationFactoryBean" />
    </bean>

    <bean name="configurationFactoryBean"
        class="org.springmodules.commons.configuration.CommonsConfigurationFactoryBean">
        <property name="configurations" ref="applicationProperties" />
    </bean>


    <bean id="applicationProperties" class="org.apache.commons.configuration.DatabaseConfiguration">
        <constructor-arg type="javax.sql.DataSource" ref="myDataSource" />
        <constructor-arg index="1" value="dbo.APPLICATIONPROPERTIES" />
        <constructor-arg index="2" value="NAME" />
        <constructor-arg index="3" value="VALUE" />
    </bean>

i can then get the what ever property i want using the getProperty() method and passing the NAME variable 然后,我可以使用getProperty()方法并传递NAME变量来获取所需的属性

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM