一般系统中spring配置文件的加载都是在系统启动的时候进行的,启动之后系统就可以获得配置文件定义的Bean了。但希望不重新启动系统,系统又可以在运行过程动态加载配置文件获得新定义的Bean时,改怎样实现呢?本文给出了一个通过动态加载配置文件实现数据源切换功能的过程。
因为不同的数据源是通过不同的spring配置文件进行定义的,所以下面先给出spring文件的配置内容。针对Oracle数据库,先编写一个OracleDatasourceContext.xml的文件,该文件定义了一个ApplicationContext类型的Bean,该Bean负责加载相应的数据源,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- Just keep one bean in this file, don't define more !-->
<bean id="DataSourceContext"
class="org.springframework.context.support.ClassPathXmlApplicationContext" lazy-init="true">
<constructor-arg>
<list>
<value>config/common/OracleDataSource.xml</value>
</list>
</constructor-arg>
</bean>
</beans>
然后在OracheDataSource.xml中定义了数据源的实现类,这里采用apache提供的数据源实现类,配置如下:
<?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="getSysDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@10.10.7.111:1521:hccdev"/>
<property name="username" value="TMCII"/>
<property name="password" value="TMCII"/>
</bean>
</beans>
同样,为了实现支持mysql数据源的功能,也需要定义两个这样的配置文件,一个和上面的OracleDatasourceContext.xml配置文件相对应,文件名为MySQLDatasourceContext.xml,该文件中定义了一个ApplicationContext类型的Bean,该Bean加载名称为mySQLDataSource.xml的配置文件,mySQLDataSource.xml和上面的OracheDataSource.xml相对应,该文件定义了一个针对mysql数据库的数据源实现。
配置文件定义完了,需要调用Oracle数据库对应的数据源时,改如何做呢?这就需要用到spring提供的名称为org.springframework.beans.factory.access.SingletonBeanFactoryLocator的类来实现,过程如下:首先,由于该类是一个工厂类,通过调用类中的getInstance(String selector)方法就可以获得一个SingletonBeanFactoryLocator的实例,selector参数就是定义了AppcationContext类型Bean的配置文件所在的路径,就比如上面的OracleDatasourceContext.xml和MySQLDatasourceContext.xml。获得了一个定位器的实例后,就可以调用SingletonBeanFactoryLocator中的useBeanFactory(String factoryKey)方法得到配置文件中定义的BeanFactory,这里是ClassPathXmlApplicationContext的具体实现类,该方法中参数factoryKey就是配置文件中的DataSourceContext。得到BeanFactory之后,就对其可以进行初始化,让它加载对应的数据源配置文件。然后通过BeanFactory的getBean方法就可以获得配置文件中定义的具体的数据源实现。经过这些步骤之后,整个功能就完成了,实现代码如下:
String dataSourceContext="OracleDatasourceContext.xml";
String contextKey="dataSourceContext";
Strinb beanId="getSysDataSource";
BeanFactoryLocator sysCtxLocator = SingletonBeanFactoryLocator.getInstance(dataSourceContext);
BeanFactoryReference brf = sysCtxLocator .useBeanFactory(contextKey);
DataSource ds=brf.getFactory().getBean(beanId);
上面的代码的功能是获得Oracle对应的数据源,把代码中的dataSourceContext赋值为mySQLDataSourceContext.xml就可以获得mysql对应的数据源了。