AbstractRoutingDataSource - 动态数据源

Posted xiaotian1001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AbstractRoutingDataSource - 动态数据源相关的知识,希望对你有一定的参考价值。

AbstractRoutingDataSource 类说明:
(1)它的抽象方法 determineCurrentLookupKey() 决定使用哪个数据源。
(2)项目启动时,先调用 setTargetDataSources() 方法,然后框架调用 afterPropertiesSet() 方法。
后续需要实时刷新数据源时,需要手动调用以上两个方法!
(3)我们手动提交给 setTargetDataSources 方法的是用来初始化 targetDataSources 的入参,一个 Map<Stirng, DataSource> 结构的对象。但是执行数据库操作时,是从 resolvedDataSources 对象中获取数据源的,afterPropertiesSet() 方法就是用来初始化后者的!

DataSourceContextHolder-切换数据源

public class DynamicDataSourceContextHolder {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
    public static void setDataSourceKey(String key) {
        contextHolder.set(key);
    }
    public static String getDataSourceKey() {
        return contextHolder.get();
    }
    public static void clearDataSourceKey() {
        contextHolder.remove();
    }
}

RoutingDataSource - AbstractRoutingDataSource子类

public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceContextHolder.getDataSourceKey();
    }
}

RoutingDataSourceConfig - 配置类

@Configuration
public class DynamicDataSourceConfig {
    @Autowired
    private DataSource dataSourceDefault;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    private DataSource createDataSource(Map<String, Object> map) {
        DruidDecryptDataSource dataSource = new DruidDecryptDataSource();
        dataSource.setDriverClassName(map.get("DRIVER_CLASS_NAME").toString());
        dataSource.setUrl(map.get("URL").toString());
        dataSource.setUsername(map.get("USERNAME").toString());
        dataSource.setPassword(map.get("PASSWORD").toString());
        dataSource.setMaxWait(10000);//10s
        return dataSource;
    }
    public Map<Object, Object> dataSourceMap() {
        List<Map<String, Object>> list = jdbcTemplate.queryForList("select * from dataSource");
        Map<Object, Object> returnMap = new HashMap<Object, Object>();
        for(Map<String, Object> map : list) {
            returnMap.put(map.get("DATASOURCE_NAME"), createDataSource(map));
        }
        return returnMap;
    }
    @Bean("dataSource")
    public DynamicDataSource dataSource() {
        DynamicDataSource ddataSource = new DynamicDataSource();
        ddataSource.setDefaultTargetDataSource(dataSourceDefault);// 设置默认数据源
        ddataSource.setTargetDataSources(dataSourceMap());
        return ddataSource;
    }
    @Bean("jdbcTemplate")
    public NamedParameterJdbcTemplate jdbcTemplate(@Qualifier("dataSource") DynamicDataSource dataSource) {
        return new NamedParameterJdbcTemplate(new JdbcTemplate(dataSource));
    }
}




以上是关于AbstractRoutingDataSource - 动态数据源的主要内容,如果未能解决你的问题,请参考以下文章

AbstractRoutingDataSource - 动态数据源

AbstractRoutingDataSource实现动态数据源切换 专题

切换数据库+ThreadLocal+AbstractRoutingDataSource

带有注释和(动态)AbstractRoutingDataSource 的 Spring 3.1.3 + Hibernate 配置

AbstractRoutingDataSource 实现动态数据源切换原理简单分析

AbstractRoutingDataSource 在运行时更改映射