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


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部