Spring动态注册bean实现动态多数据源(一)

2014-11-24 09:46:30 · 作者: · 浏览: 5

项目原来已经实现了多数据源配置,实现方式为在beans.xml文件中直接配置多个数据源bean,然后在使用数据源时通过HotSwappableTargetSource动态切换数据源(详细内容请Google)。可领导不满意,要求只在属性文件中配置相应的连接信息,并要求动态数据源除配置的属性外,其他属性都继承系统默认数据源(DataSource)的属性。然后给出的属性文件中数据源的格式为:

[plain]
#连接数据库地址,该地址可动态添加,“link.”之后,“.jdbc”之前的名称为数据库连接池的名称,其余连接池属性如果不写,将自动继承Hummer的数据库连接池配置
link.eagle2.business.jdbc.jdbcUrl=jdbc:oracle:thin:@192.168.0.155:1521:orcl
link.eagle2.business.jdbc.user=eagle2
link.eagle2.business.jdbc.password=eagle2_password
link.eagle2.interface.jdbc.jdbcUrl=jdbc:oracle:thin:@192.168.0.155:1521:interface
link.eagle2.interface.jdbc.user=interface
link.eagle2.interface.jdbc.password=interface22
link.eagle2.ods.jdbc.jdbcUrl=jdbc:oracle:thin:@192.168.0.10:1521:sifen
link.eagle2.ods.jdbc.user=honghe
link.eagle2.ods.jdbc.password=honghe_pwd

为实现这个要求,我经过google搜索,写代码尝试,最后终于较好的实现了该功能,结果记录如下:
实现一个实现ApplicationContextAware和ApplicationListener接口的类DynamicDataSourceC3p0,实现ApplicationContextAware是为了得到ApplicationContext,实现了ApplicationListener是为了配置spring的加载事件。
类的实现代码如下:
[java]
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.ChildBeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.io.support.ResourcePropertySource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class DynamicDataSourceC3p0 implements ApplicationContextAware,ApplicationListener {

private ApplicationContext app;
@Override
public void setApplicationContext(ApplicationContext app)
throws BeansException {
this.app = app;
}
public void onApplicationEvent(ApplicationEvent event) {
//如果是容器刷新事件
if(event instanceof ContextRefreshedEvent ){//如果是容器关闭事件
try {
regDynamicBean();
} catch (IOException e) {
e.printStackTrace();
}
//System.out.println(event.getClass().getSimpleName()+" 事件已发生!");
}
}

private void regDynamicBean() throws IOException{
// 解析属性文件,得到数据源Map
Map mapCustom = parsePropertiesFile("hummer.properties");
// 把数据源bean注册到容器中
addSourceBeanToApp(mapCustom);

}
/**
* 功能说明:根据DataSource创建bean并注册到容器中
* @param acf
* @param mapCustom
*/
private void addSourceBeanToApp(Map mapCustom) {
DefaultListableBeanFactory acf = (DefaultListableBeanFactory) app.getAutowireCapableBeanFactory();
BeanDefinition beanDefinition;
Iterator iter = mapCustom.keySet().iterator();
while(iter.hasNext()){