java 页面动态加载数据库连接_Spring配置动态数据源(动态添加免重启)
Spring +driuid 动态切换数据源,数据源连接池使用druid 其他的数据源原理基本相同
spring中配置默认数据源连接池如下:
接下来在spring-context.xml中配置多数据源bean,
这个类 com.XXX.datasource.DynamicDataSource 需要手动创建重写了spring管理数据源的方法import java.sql.DriverManager;
import java.util.Map;
import java.util.Set;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.util.StringUtils;
/**
* @author zh
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
private boolean debug = false;
Logger log = LoggerFactory.getLogger(this.getClass());
private Map dynamicTargetDataSources;
private Object dynamicDefaultTargetDataSource;
@Override
protected Object determineCurrentLookupKey() {
String datasource = DBContextHolder.getDataSource();
if (debug) {
if (StringUtils.isEmpty(datasource)) {
log.info("---当前数据源:默认数据源---");
} else {
log.info("---当前数据源:" + datasource + "---");
}
}
return datasource;
}
@Override
public void setTargetDataSources(Map targetDataSources) {
super.setTargetDataSources(targetDataSources);
this.dynamicTargetDataSources = targetDataSources;
}
// 创建数据源
public boolean createDataSource(String key, String driveClass, String url, String username, String password) {
try {
try { // 排除连接不上的错误
Class.forName(driveClass);
DriverManager.getConnection(url, username, password);// 相当于连接数据库
} catch (Exception e) {
return false;
}
@SuppressWarnings("resource")
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setName(key);
druidDataSource.setDriverClassName(driveClass);
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
druidDataSource.setMaxWait(60000);
druidDataSource.setFilters("stat");
DataSource createDataSource = (DataSource) druidDataSource;
druidDataSource.init();
Map dynamicTargetDataSources2 = this.dynamicTargetDataSources;
dynamicTargetDataSources2.put(key, createDataSource);// 加入map
setTargetDataSources(dynamicTargetDataSources2);// 将map赋值给父类的TargetDataSources
super.afterPropertiesSet();// 将TargetDataSources中的连接信息放入resolvedDataSources管理
return true;
} catch (Exception e) {
log.error(e + "");
return false;
}
}
// 删除数据源
public boolean delDatasources(String datasourceid) {
Map dynamicTargetDataSources2 = this.dynamicTargetDataSources;
if (dynamicTargetDataSources2.containsKey(datasourceid)) {
Set druidDataSourceInstances = DruidDataSourceStatManager.getDruidDataSourceInstances();
for (DruidDataSource l : druidDataSourceInstances) {
if (datasourceid.equals(l.getName())) {
System.out.println(l);
dynamicTargetDataSources2.remove(datasourceid);
DruidDataSourceStatManager.removeDataSource(l);
setTargetDataSources(dynamicTargetDataSources2);// 将map赋值给父类的TargetDataSources
super.afterPropertiesSet();// 将TargetDataSources中的连接信息放入resolvedDataSources管理
return true;
}
}
return false;
} else {
return false;
}
}
// 测试数据源连接是否有效
public boolean testDatasource(String key, String driveClass, String url, String username, String password) {
try {
Class.forName(driveClass);
DriverManager.getConnection(url, username, password);
return true;
} catch (Exception e) {
return false;
}
}
/**
* Specify the default target DataSource, if any.
*
* The mapped value can either be a corresponding
* {@link javax.sql.DataSource} instance or a data source name String (to be
* resolved via a {@link #setDataSourceLookup DataSourceLookup}).
*
* This DataSource will be used as target if none of the keyed
* {@link #setTargetDataSources targetDataSources} match the
* {@link #determineCurrentLookupKey()} current lookup key.
*/
public void setDefaultTargetDataSource(Object defaultTargetDataSource) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
this.dynamicDefaultTargetDataSource = defaultTargetDataSource;
}
/**
* @param debug
* the debug to set
*/
public void setDebug(boolean debug) {
this.debug = debug;
}
/**
* @return the debug
*/
public boolean isDebug() {
return debug;
}
/**
* @return the dynamicTargetDataSources
*/
public Map getDynamicTargetDataSources() {
return dynamicTargetDataSources;
}
/**
* @param dynamicTargetDataSources
* the dynamicTargetDataSources to set
*/
public void setDynamicTargetDataSources(Map dynamicTargetDataSources) {
this.dynamicTargetDataSources = dynamicTargetDataSources;
}
/**
* @return the dynamicDefaultTargetDataSource
*/
public Object getDynamicDefaultTargetDataSource() {
return dynamicDefaultTargetDataSource;
}
/**
* @param dynamicDefaultTargetDataSource
* the dynamicDefaultTargetDataSource to set
*/
public void setDynamicDefaultTargetDataSource(Object dynamicDefaultTargetDataSource) {
this.dynamicDefaultTargetDataSource = dynamicDefaultTargetDataSource;
}
}
�其中该类继承了spring的AbstractRoutingDataSource 查看其源码,发现所有的数据源都是通过afterPropertiesSet() 将存放在targetDataSources 这个Map中的数据源赋值给resolvedDataSources对象的,spring是从resolvedDataSources对象中获取数据源对象的,我们能需要把自己的数据源放入resolvedDataSources这个Map中就ok了。�
接下来创建数据源切换工具类�/**
* 数据源切换
*
* @author zh
*
*/
public class DBContextHolder {
// 对当前线程的操作-线程安全的
private static final ThreadLocal contextHolder = new ThreadLocal();
// 调用此方法,切换数据源
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
// 获取数据源
public static String getDataSource() {
return contextHolder.get();
}
// 删除数据源
public static void clearDataSource() {
contextHolder.remove();
}
}�
具体实动态新增数据源,需要创建数据库用以存储 数据库连接信息,以及数据源key信息。
初始话数据库连接数据源,可以使用spring监听 实现ApplicationListener即可,需要在spring配置文件中配置初始化加载binimport java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import com.casking.cdds.modules.datasource.entity.CNDatasources;
public class InitDatasourcesLS implements ApplicationListener {
@Autowired
private CNDatasourcesService service;
@Override
public void onApplicationEvent(ApplicationEvent event) {
List list = service.findList(new CNDatasources());
for (CNDatasources li : list) {
// 这里调用创建数据源的方法即可
service.addDataSourceDynamic(li.getDatasource(), li);
}
}
}
来源网站:太平洋学习网,转载请注明出处:http://www.tpyyes.com/a/javaweb/192.html
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!