PropertyPlaceholderConfigurer 用于读取 属性 个文件和数据库
PropertyPlaceholderConfigurer for reading property files and database
我正在尝试创建两个 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>
我有以下 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>
这对我的应用程序的其余部分非常有效,除非我尝试将它用于我的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
如果我在 ComboPooledDataSource
中对数据库变量进行硬编码(例如,将 ${jdbc.driverClassName}
更改为 net.sourceforge.jtds.jdbc.Driver
一切正常,但由于某种原因,当我添加 otherPropertyConfigurer
时,我的原始propertyConfigurer
无效
有没有人知道如何解决这个问题?
我不想成为坏消息的旁观者,但你想要达到的目标,Spring身体上做不到。
因为 Springs PropertyPlaceholderConfigurer 类 作为 beanPostProcessors,它在创建任何其他 bean 之前创建并调用这些 bean。但是,如果您有多个 PropertyPlaceholderConfigurer,其中一个依赖于另一个,Spring 将始终在调用其中任何一个之前完全创建两个实例。因此,您在 myDataSource 中的占位符永远无法解析。
问题在 this question 中有更好的描述。
解决此问题的最佳方法通常是停止使用数据库进行配置管理。我发现最好使用一个简单的配置文件,它可以根据环境进行修改,并托管在您的部署容器中。
正如 ConMan 所建议的那样,这不能按照我在上面的问题中解释的方式来完成。但是我已经设法解决了这个问题,而是使用以下代码
将属性 (propertiesFromDB
) 传递到 class
<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>
然后我可以使用 getProperty()
方法并传递 NAME
变量
得到我想要的 属性
我正在尝试创建两个 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>
我有以下 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>
这对我的应用程序的其余部分非常有效,除非我尝试将它用于我的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
如果我在 ComboPooledDataSource
中对数据库变量进行硬编码(例如,将 ${jdbc.driverClassName}
更改为 net.sourceforge.jtds.jdbc.Driver
一切正常,但由于某种原因,当我添加 otherPropertyConfigurer
时,我的原始propertyConfigurer
无效
有没有人知道如何解决这个问题?
我不想成为坏消息的旁观者,但你想要达到的目标,Spring身体上做不到。
因为 Springs PropertyPlaceholderConfigurer 类 作为 beanPostProcessors,它在创建任何其他 bean 之前创建并调用这些 bean。但是,如果您有多个 PropertyPlaceholderConfigurer,其中一个依赖于另一个,Spring 将始终在调用其中任何一个之前完全创建两个实例。因此,您在 myDataSource 中的占位符永远无法解析。
问题在 this question 中有更好的描述。
解决此问题的最佳方法通常是停止使用数据库进行配置管理。我发现最好使用一个简单的配置文件,它可以根据环境进行修改,并托管在您的部署容器中。
正如 ConMan 所建议的那样,这不能按照我在上面的问题中解释的方式来完成。但是我已经设法解决了这个问题,而是使用以下代码
将属性 (propertiesFromDB
) 传递到 class
<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>
然后我可以使用 getProperty()
方法并传递 NAME
变量