赞
踩
Spring的多数据源支持---AbstractRoutingDataSource,AbstractRoutingDataSource定义了抽象的determineCurrentLookupKey方法,子类实现此方法,来确定要使用的数据源
- public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {
- protected DataSource determineTargetDataSource() {
- Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
- Object lookupKey = determineCurrentLookupKey();
- DataSource dataSource = this.resolvedDataSources.get(lookupKey);
- if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
- dataSource = this.resolvedDefaultDataSource;
- }
- if (dataSource == null) {
- throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
- }
- return dataSource;
- }
-
- // 确定当前要使用的数据源
- protected abstract Object determineCurrentLookupKey();
- }

Druid 实现多数据源支持,核心是Overwrite AbstractRoutingDataSource 的 determineCurrentLookupKey 方法
- public class MultipleDataSource extends AbstractRoutingDataSource {
- public static final String DATA_SOURCE_A = "dataSourceTestA"; // A库
- public static final String DATA_SOURCE_B = "dataSourceTestB"; // B库
-
- private static final ThreadLocal<String> dataSourceKey = new ThreadLocal<String>();
-
- public static void setDataSourceKey(String dataSource) {
- dataSourceKey.set(dataSource);
- }
-
- @Override
- protected Object determineCurrentLookupKey() {
- return dataSourceKey.get();
- }
-
- public static void clear(){
- dataSourceKey.remove();
- }
- }

AbstractRoutingDataSourceApplication实战:
DataSourceLeonProperties
- package center.leon.oak.druid.abstract_routing_data_source.properties;
-
- import lombok.Data;
- import lombok.experimental.Accessors;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.stereotype.Component;
-
- import java.util.List;
-
- /**
- * @program: leon
- * @description:
- * @author: Leon
- * @create: 2021-07-22 13:56
- **/
- @Data
- @Component
- @ConfigurationProperties(value = "spring.datasource.leon")
- public class DataSourceLeonProperties {
-
- /**
- * 默认数据源
- */
- private DataSourceLeon defaultDataSourceLeon;
- /**
- * 数据源列表
- */
- private List<DataSourceLeon> dataSourceLeonList;
-
-
- /**
- * 自定义数据源
- */
- @Data
- @Accessors(chain = true)
- public static class DataSourceLeon {
- /**
- * 数据源自定义名称
- */
- private String dataSourceName;
- /**
- * 数据源驱动
- */
- private String driverClassName;
- /**
- * 数据源URL
- */
- private String url;
- /**
- *
- */
- private String username;
- /**
- *
- */
- private String password;
- }
- }

MultipleDataSource
- package center.leon.oak.druid.abstract_routing_data_source.config;
-
- import center.leon.oak.druid.abstract_routing_data_source.properties.DataSourceLeonProperties;
- import com.alibaba.druid.pool.DruidDataSource;
- import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
- import org.springframework.beans.factory.InitializingBean;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
- import org.springframework.stereotype.Component;
-
- import java.util.HashMap;
- import java.util.Map;
-
- /**
- * @program: leon
- * @description:
- * @author: Leon
- * @create: 2021-07-22 11:31
- **/
- @Component
- public class MultipleDataSource extends AbstractRoutingDataSource implements InitializingBean {
-
- ThreadLocal<String> data_source_name = new ThreadLocal<>();
-
- @Autowired
- private DataSourceLeonProperties datasourceLeonProperties;
-
- @Override
- public void afterPropertiesSet() {
- init();
- }
-
- private void init() {
- // 设置默认数据源
- if (null != datasourceLeonProperties.getDefaultDataSourceLeon()) {
- DataSourceLeonProperties.DataSourceLeon dataSourceLeon = datasourceLeonProperties.getDefaultDataSourceLeon();
- DruidDataSource druidDataSource = DruidDataSourceBuilder.create().build();
- druidDataSource.setDriverClassName(dataSourceLeon.getDriverClassName());
- druidDataSource.setUrl(dataSourceLeon.getUrl());
- druidDataSource.setUsername(dataSourceLeon.getUsername());
- druidDataSource.setPassword(dataSourceLeon.getPassword());
- super.setDefaultTargetDataSource(druidDataSource);
- }
-
- // 设置多数据源
- Map<Object, Object> targetDataSources = new HashMap<>();
- for (DataSourceLeonProperties.DataSourceLeon dataSourceLeon : datasourceLeonProperties.getDataSourceLeonList()) {
- DruidDataSource druidDataSource = DruidDataSourceBuilder.create().build();
- druidDataSource.setDriverClassName(dataSourceLeon.getDriverClassName());
- druidDataSource.setUrl(dataSourceLeon.getUrl());
- druidDataSource.setUsername(dataSourceLeon.getUsername());
- druidDataSource.setPassword(dataSourceLeon.getPassword());
-
- targetDataSources.put(dataSourceLeon.getDataSourceName(), druidDataSource);
- }
- super.setTargetDataSources(targetDataSources);
-
- // 调用父类 afterPropertiesSet 方法
- // 将 targetDataSources 数据 填充到 resolvedDataSources 中
- // determineCurrentLookupKey 返回的 lookupKey 本质上是在 resolvedDataSources 中查找 dataSource 返回
- // 将 defaultTargetDataSource 数据 填充到 resolvedDefaultDataSource 中
- // resolvedDataSources 中 查找不到合适的 dataSource 时返回。
- super.afterPropertiesSet();
- }
-
- @Override
- protected Object determineCurrentLookupKey() {
- return data_source_name.get();
- }
-
- public void setDb_tb_name(String dataSourceName) {
- data_source_name.set(dataSourceName);
- }
-
- public void clearDb_tb_name() {
- data_source_name.remove();
- }
- }

MonkeyDO
- package center.leon.oak.druid.abstract_routing_data_source.dto;
-
- import com.baomidou.mybatisplus.annotation.TableName;
- import lombok.Data;
- import lombok.experimental.Accessors;
-
- /**
- * @program: leon
- * @description:
- * @author: Leon
- * @create: 2021-07-22 12:05
- **/
- @Data
- @TableName(value = "monkey")
- @Accessors(chain = true)
- public class MonkeyDO {
- private Long id;
- private String name;
- private Long version;
- }

MonkeyMapper
- package center.leon.oak.druid.abstract_routing_data_source.mapper;
-
- import center.leon.oak.druid.abstract_routing_data_source.dto.MonkeyDO;
- import com.baomidou.mybatisplus.core.mapper.BaseMapper;
- import org.apache.ibatis.annotations.Mapper;
-
- /**
- * @program: leon
- * @description:
- * @author: Leon
- * @create: 2021-07-22 12:04
- **/
- @Mapper
- public interface MonkeyMapper extends BaseMapper<MonkeyDO> {
- }
MonkeyService
- package center.leon.oak.druid.abstract_routing_data_source.service;
-
- import center.leon.oak.druid.abstract_routing_data_source.dto.MonkeyDO;
-
- /**
- * @program: leon
- * @description:
- * @author: Leon
- * @create: 2021-07-22 12:00
- **/
- public interface MonkeyService {
-
- MonkeyDO get(Long id);
-
- MonkeyDO getInDataSource(Long id, String dataSourceName);
- }

MonkeyServiceImpl
- package center.leon.oak.druid.abstract_routing_data_source.service.impl;
-
- import center.leon.oak.druid.abstract_routing_data_source.config.MultipleDataSource;
- import center.leon.oak.druid.abstract_routing_data_source.dto.MonkeyDO;
- import center.leon.oak.druid.abstract_routing_data_source.mapper.MonkeyMapper;
- import center.leon.oak.druid.abstract_routing_data_source.service.MonkeyService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
-
- /**
- * @program: leon
- * @description:
- * @author: Leon
- * @create: 2021-07-22 12:03
- **/
- @Service
- public class MonkeyServiceImpl implements MonkeyService {
-
- @Autowired
- private MonkeyMapper monkeyMapper;
- @Autowired
- private MultipleDataSource multipleDataSource;
-
- @Override
- public MonkeyDO get(Long id) {
- return monkeyMapper.selectById(id);
- }
-
- @Override
- public MonkeyDO getInDataSource(Long id, String dataSourceName) {
- try {
- multipleDataSource.setDb_tb_name(dataSourceName);
- return monkeyMapper.selectById(id);
- } finally {
- multipleDataSource.clearDb_tb_name();
- }
- }
- }

PrintMonkey
- package center.leon.oak.druid.abstract_routing_data_source.task;
-
- import center.leon.oak.druid.abstract_routing_data_source.dto.MonkeyDO;
- import center.leon.oak.druid.abstract_routing_data_source.service.MonkeyService;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.scheduling.annotation.Scheduled;
- import org.springframework.stereotype.Component;
-
- /**
- * @program: leon
- * @description:
- * @author: Leon
- * @create: 2021-07-22 21:28
- **/
- @Slf4j
- @Component
- public class PrintMonkey {
-
- @Autowired
- private MonkeyService monkeyService;
-
- @Scheduled(fixedRate = 6 * 1000)
- public void printMonkey_localhost() {
- MonkeyDO monkeyDO = monkeyService.getInDataSource(1L, "localhost");
- log.info("threadName : {}, monkey : {}", Thread.currentThread().getName(), monkeyDO);
- }
-
- @Scheduled(fixedRate = 6 * 1000)
- public void printMonkey_www_leon_center() {
- MonkeyDO monkeyDO = monkeyService.getInDataSource(1L, "www_leon_center");
- log.info("threadName : {}, monkey : {}", Thread.currentThread().getName(), monkeyDO);
- }
- }

application-druid.properties
- spring.datasource.type=center.leon.oak.druid.abstract_routing_data_source.config.MultipleDataSource
-
- spring.datasource.leon.data-source-leon-list[0].data-source-name=localhost
- spring.datasource.leon.data-source-leon-list[0].driver-class-name=com.mysql.cj.jdbc.Driver
- spring.datasource.leon.data-source-leon-list[0].url=jdbc:mysql://localhost:3306/zoo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false
- spring.datasource.leon.data-source-leon-list[0].username=root
- spring.datasource.leon.data-source-leon-list[0].password=Liang123,
-
- spring.datasource.leon.data-source-leon-list[1].data-source-name=www_leon_center
- spring.datasource.leon.data-source-leon-list[1].driver-class-name=com.mysql.cj.jdbc.Driver
- spring.datasource.leon.data-source-leon-list[1].url=jdbc:mysql://www.leon.center:3306/zoo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false
- spring.datasource.leon.data-source-leon-list[1].username=lmy
- spring.datasource.leon.data-source-leon-list[1].password=Lmy123456,
-
-
- spring.task.scheduling.pool.size=2

AbstractRoutingDataSourceApplication
- package center.leon.oak.druid.abstract_routing_data_source;
-
- import center.leon.oak.druid.abstract_routing_data_source.config.MultipleDataSource;
- import center.leon.oak.druid.abstract_routing_data_source.dto.MonkeyDO;
- import center.leon.oak.druid.abstract_routing_data_source.properties.DataSourceLeonProperties;
- import center.leon.oak.druid.abstract_routing_data_source.service.MonkeyService;
- import center.leon.oak.druid.abstract_routing_data_source.service.impl.MonkeyServiceImpl;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.boot.context.properties.EnableConfigurationProperties;
- import org.springframework.context.ConfigurableApplicationContext;
- import org.springframework.scheduling.annotation.EnableScheduling;
-
- /**
- * @program: leon
- * @description:
- * @author: Leon
- * @create: 2021-07-22 11:28
- **/
- @Slf4j
- @EnableScheduling
- @EnableConfigurationProperties
- @SpringBootApplication
- public class AbstractRoutingDataSourceApplication {
- public static void main(String[] args) {
- ConfigurableApplicationContext run = SpringApplication.run(AbstractRoutingDataSourceApplication.class, args);
- DataSourceLeonProperties dataSourceLeonProperties = run.getBean(DataSourceLeonProperties.class);
- log.info("dataSourceLeonProperties : {}", dataSourceLeonProperties);
- MonkeyService monkeyService = run.getBean(MonkeyServiceImpl.class);
-
- final MultipleDataSource multipleDataSource = run.getBean(MultipleDataSource.class);
-
- multipleDataSource.setDb_tb_name("localhost");
- MonkeyDO monkey_1 = monkeyService.get(1L);
- log.info("monkey_1 : {}", monkey_1);
- multipleDataSource.clearDb_tb_name();
-
- multipleDataSource.setDb_tb_name("www_leon_center");
- MonkeyDO monkey_2 = monkeyService.get(1L);
- log.info("monkey_2 : {}", monkey_2);
- multipleDataSource.clearDb_tb_name();
- }
- }

Console
- 2021-07-22 22:11:39.813 INFO 69282 --- [ main] d.a.AbstractRoutingDataSourceApplication : show Time ...
- 2021-07-22 22:11:39.813 INFO 69282 --- [ main] d.a.AbstractRoutingDataSourceApplication : dataSourceLeonProperties : DataSourceLeonProperties(defaultDataSourceLeon=null, dataSourceLeonList=[DataSourceLeonProperties.DataSourceLeon(dataSourceName=localhost, driverClassName=com.mysql.cj.jdbc.Driver, url=jdbc:mysql://localhost:3306/zoo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false, username=root, password=Liang123,), DataSourceLeonProperties.DataSourceLeon(dataSourceName=www_leon_center, driverClassName=com.mysql.cj.jdbc.Driver, url=jdbc:mysql://www.leon.center:3306/zoo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false, username=lmy, password=Lmy123456,)])
- 2021-07-22 22:11:39.864 INFO 69282 --- [ scheduling-2] com.alibaba.druid.pool.DruidDataSource : {dataSource-2} inited
- 2021-07-22 22:11:39.864 INFO 69282 --- [ main] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited
- 2021-07-22 22:11:40.026 INFO 69282 --- [ main] d.a.AbstractRoutingDataSourceApplication : monkey_1 : MonkeyDO(id=1, name=write, version=2)
- 2021-07-22 22:11:40.026 INFO 69282 --- [ scheduling-1] c.l.o.d.a.task.PrintMonkey : threadName : scheduling-1, monkey : MonkeyDO(id=1, name=write, version=2)
- 2021-07-22 22:11:40.067 INFO 69282 --- [ scheduling-2] c.l.o.d.a.task.PrintMonkey : threadName : scheduling-2, monkey : MonkeyDO(id=1, name=monkey sun, version=500)
- 2021-07-22 22:11:40.075 INFO 69282 --- [ main] d.a.AbstractRoutingDataSourceApplication : monkey_2 : MonkeyDO(id=1, name=monkey sun, version=500)
- 2021-07-22 22:11:40.367 INFO 69282 --- [on(3)-127.0.0.1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
- 2021-07-22 22:11:40.367 INFO 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
- 2021-07-22 22:11:40.367 TRACE 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.multipart.support.StandardServletMultipartResolver@42d0e41
- 2021-07-22 22:11:40.367 TRACE 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver@48f2054d
- 2021-07-22 22:11:40.367 TRACE 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.theme.FixedThemeResolver@6d6cd1e0
- 2021-07-22 22:11:40.368 TRACE 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet : Detected DefaultRequestToViewNameTranslator
- 2021-07-22 22:11:40.369 TRACE 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet : Detected SessionFlashMapManager
- 2021-07-22 22:11:40.369 DEBUG 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
- 2021-07-22 22:11:40.369 INFO 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms
- 2021-07-22 22:11:45.812 INFO 69282 --- [ scheduling-1] c.l.o.d.a.task.PrintMonkey : threadName : scheduling-1, monkey : MonkeyDO(id=1, name=write, version=2)
- 2021-07-22 22:11:45.824 INFO 69282 --- [ scheduling-2] c.l.o.d.a.task.PrintMonkey : threadName : scheduling-2, monkey : MonkeyDO(id=1, name=monkey sun, version=500)
- 2021-07-22 22:11:51.808 INFO 69282 --- [ scheduling-1] c.l.o.d.a.task.PrintMonkey : threadName : scheduling-1, monkey : MonkeyDO(id=1, name=write, version=2)
- 2021-07-22 22:11:51.822 INFO 69282 --- [ scheduling-2] c.l.o.d.a.task.PrintMonkey : threadName : scheduling-2, monkey : MonkeyDO(id=1, name=monkey sun, version=500)
- 2021-07-22 22:11:57.807 INFO 69282 --- [ scheduling-1] c.l.o.d.a.task.PrintMonkey : threadName : scheduling-1, monkey : MonkeyDO(id=1, name=write, version=2)
- 2021-07-22 22:11:57.818 INFO 69282 --- [ scheduling-2] c.l.o.d.a.task.PrintMonkey : threadName : scheduling-2, monkey : MonkeyDO(id=1, name=monkey sun, version=500)
- 2021-07-22 22:12:03.809 INFO 69282 --- [ scheduling-1] c.l.o.d.a.task.PrintMonkey : threadName : scheduling-1, monkey : MonkeyDO(id=1, name=write, version=2)
- 2021-07-22 22:12:04.051 INFO 69282 --- [ scheduling-2] c.l.o.d.a.task.PrintMonkey : threadName : scheduling-2, monkey : MonkeyDO(id=1, name=monkey sun, version=500)
- 2021-07-22 22:12:09.811 INFO 69282 --- [ scheduling-1] c.l.o.d.a.task.PrintMonkey : threadName : scheduling-1, monkey : MonkeyDO(id=1, name=write, version=2)
- 2021-07-22 22:12:09.824 INFO 69282 --- [ scheduling-2] c.l.o.d.a.task.PrintMonkey : threadName : scheduling-2, monkey : MonkeyDO(id=1, name=monkey sun, version=500)
- 2021-07-22 22:12:15.810 INFO 69282 --- [ scheduling-1] c.l.o.d.a.task.PrintMonkey : threadName : scheduling-1, monkey : MonkeyDO(id=1, name=write, version=2)
- 2021-07-22 22:12:15.821 INFO 69282 --- [ scheduling-2] c.l.o.d.a.task.PrintMonkey : threadName : scheduling-2, monkey : MonkeyDO(id=1, name=monkey sun, version=500)

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。