在代码上定义DataSource bean

时间:2010-03-14 19:35:05

标签: spring datasource

我想在我的spring应用程序中创建一个“First Access Database Setup Process”,我唯一想象的解决方案就是以编程方式初始化DataSource bean。

我当前的bean定义为:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/catalog" />
    <property name="username" value="condominium" />
    <property name="password" value="password" />
    <property name="validationQuery" value="SELECT 1" />
    <property name="testOnBorrow" value="true" />
    <property name="defaultAutoCommit" value="false" />
    <property name="maxWait" value="5000" />
</bean>

但理想的是在我需要的时候自己加载它并使用我定义的参数。

场景是用户(管理员)第一次来到应用程序,我问他要连接的服务器,端口和目录。我将它存储在一个embeeded db中,下次应用程序启动时,bean可以检查是否在嵌入式db上设置了参数并重新加载它。

有可能吗?

EDT: 每个@axtavt sugestion我都会带着代理......

<bean id="dataSource" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="targetSource" ref="swappableDataSource"/>
</bean>
<bean name="swappableDataSource" class="org.springframework.aop.target.HotSwappableTargetSource">
    <constructor-arg ref="dummyDataSource"/>
</bean>
<bean id="dummyDataSource" factory-bean="dataSourceFactory" factory-method="createDataSource" destroy-method="close"/>
<bean id="dataSourceFactory" class="com.condominium.spring.factory.DataSourceFactory"/>

一旦使用代理实现了如何将其转换为原始Bean?

Object o = ctx.getBean("dataSource");
BasicDataSource ds = (BasicDataSource)o;

将抛出 java.lang.ClassCastException:$ Proxy4无法强制转换为org.apache.commons.dbcp.BasicDataSource

3 个答案:

答案 0 :(得分:2)

您可以创建工厂以生成您想要的DataSource

<bean id = "dataSourceFactory" class = "MyFactory" />

<bean id = "dataSource" factory-bean = "dataSourceFactory" factory-method = "createDataSource" />

-

public class MyFactory {
    public DataSource createDataSource() {
        ... // produce a DataSource
    }
}

答案 1 :(得分:1)

您可以外部化数据库连接属性:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${driver}" />
    <property name="url" value="${url}" />
    <property name="username" value="${username}" />
    <property name="password" value="${password}" />
    <property name="validationQuery" value="SELECT 1" />
    <property name="testOnBorrow" value="true" />
    <property name="defaultAutoCommit" value="false" />
    <property name="maxWait" value="5000" />
</bean>

现在Spring将从启动时加载的.properties文件中获取它们。

如果您使用的是Java EE应用服务器,您还需要考虑的另一件事是JNDI连接池。您将外部化JNDI名称,连接参数由应用服务器的管理员管理。我会说这是做到这一点的首选方式。现在你仍然有一个明文密码 - 一个坏主意。

答案 2 :(得分:0)

我正在使用与您提到的完全相同的代理方法。摆脱java.lang.ClassCastException您可以从HotSwappableTargetSource bean获取dataSource,如下所示。

HotSwappableTargetSource swapper = ctx.getBean(HotSwappableTargetSource.class);
BasicDataSource ds = (BasicDataSource) swapper.getTarget();