当前位置:   article > 正文

Spring框架下利用AbstractRoutingDataSource配置多数据源_abstractroutingdatasource 如何注入datasource

abstractroutingdatasource 如何注入datasource

首先看Druid数据库多数据源Demo

Spring的多数据源支持---AbstractRoutingDataSource,AbstractRoutingDataSource定义了抽象的determineCurrentLookupKey方法,子类实现此方法,来确定要使用的数据源

  1. public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {
  2. protected DataSource determineTargetDataSource() {
  3. Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
  4. Object lookupKey = determineCurrentLookupKey();
  5. DataSource dataSource = this.resolvedDataSources.get(lookupKey);
  6. if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
  7. dataSource = this.resolvedDefaultDataSource;
  8. }
  9. if (dataSource == null) {
  10. throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
  11. }
  12. return dataSource;
  13. }
  14. // 确定当前要使用的数据源
  15. protected abstract Object determineCurrentLookupKey();
  16. }

Druid 实现多数据源支持,核心是Overwrite AbstractRoutingDataSource 的 determineCurrentLookupKey 方法

  1. public class MultipleDataSource extends AbstractRoutingDataSource {
  2. public static final String DATA_SOURCE_A = "dataSourceTestA"; // A库
  3. public static final String DATA_SOURCE_B = "dataSourceTestB"; // B库
  4. private static final ThreadLocal<String> dataSourceKey = new ThreadLocal<String>();
  5. public static void setDataSourceKey(String dataSource) {
  6. dataSourceKey.set(dataSource);
  7. }
  8. @Override
  9. protected Object determineCurrentLookupKey() {
  10. return dataSourceKey.get();
  11. }
  12. public static void clear(){
  13. dataSourceKey.remove();
  14. }
  15. }

AbstractRoutingDataSourceApplication实战:

DataSourceLeonProperties

  1. package center.leon.oak.druid.abstract_routing_data_source.properties;
  2. import lombok.Data;
  3. import lombok.experimental.Accessors;
  4. import org.springframework.boot.context.properties.ConfigurationProperties;
  5. import org.springframework.stereotype.Component;
  6. import java.util.List;
  7. /**
  8. * @program: leon
  9. * @description:
  10. * @author: Leon
  11. * @create: 2021-07-22 13:56
  12. **/
  13. @Data
  14. @Component
  15. @ConfigurationProperties(value = "spring.datasource.leon")
  16. public class DataSourceLeonProperties {
  17. /**
  18. * 默认数据源
  19. */
  20. private DataSourceLeon defaultDataSourceLeon;
  21. /**
  22. * 数据源列表
  23. */
  24. private List<DataSourceLeon> dataSourceLeonList;
  25. /**
  26. * 自定义数据源
  27. */
  28. @Data
  29. @Accessors(chain = true)
  30. public static class DataSourceLeon {
  31. /**
  32. * 数据源自定义名称
  33. */
  34. private String dataSourceName;
  35. /**
  36. * 数据源驱动
  37. */
  38. private String driverClassName;
  39. /**
  40. * 数据源URL
  41. */
  42. private String url;
  43. /**
  44. *
  45. */
  46. private String username;
  47. /**
  48. *
  49. */
  50. private String password;
  51. }
  52. }

MultipleDataSource

  1. package center.leon.oak.druid.abstract_routing_data_source.config;
  2. import center.leon.oak.druid.abstract_routing_data_source.properties.DataSourceLeonProperties;
  3. import com.alibaba.druid.pool.DruidDataSource;
  4. import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
  5. import org.springframework.beans.factory.InitializingBean;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
  8. import org.springframework.stereotype.Component;
  9. import java.util.HashMap;
  10. import java.util.Map;
  11. /**
  12. * @program: leon
  13. * @description:
  14. * @author: Leon
  15. * @create: 2021-07-22 11:31
  16. **/
  17. @Component
  18. public class MultipleDataSource extends AbstractRoutingDataSource implements InitializingBean {
  19. ThreadLocal<String> data_source_name = new ThreadLocal<>();
  20. @Autowired
  21. private DataSourceLeonProperties datasourceLeonProperties;
  22. @Override
  23. public void afterPropertiesSet() {
  24. init();
  25. }
  26. private void init() {
  27. // 设置默认数据源
  28. if (null != datasourceLeonProperties.getDefaultDataSourceLeon()) {
  29. DataSourceLeonProperties.DataSourceLeon dataSourceLeon = datasourceLeonProperties.getDefaultDataSourceLeon();
  30. DruidDataSource druidDataSource = DruidDataSourceBuilder.create().build();
  31. druidDataSource.setDriverClassName(dataSourceLeon.getDriverClassName());
  32. druidDataSource.setUrl(dataSourceLeon.getUrl());
  33. druidDataSource.setUsername(dataSourceLeon.getUsername());
  34. druidDataSource.setPassword(dataSourceLeon.getPassword());
  35. super.setDefaultTargetDataSource(druidDataSource);
  36. }
  37. // 设置多数据源
  38. Map<Object, Object> targetDataSources = new HashMap<>();
  39. for (DataSourceLeonProperties.DataSourceLeon dataSourceLeon : datasourceLeonProperties.getDataSourceLeonList()) {
  40. DruidDataSource druidDataSource = DruidDataSourceBuilder.create().build();
  41. druidDataSource.setDriverClassName(dataSourceLeon.getDriverClassName());
  42. druidDataSource.setUrl(dataSourceLeon.getUrl());
  43. druidDataSource.setUsername(dataSourceLeon.getUsername());
  44. druidDataSource.setPassword(dataSourceLeon.getPassword());
  45. targetDataSources.put(dataSourceLeon.getDataSourceName(), druidDataSource);
  46. }
  47. super.setTargetDataSources(targetDataSources);
  48. // 调用父类 afterPropertiesSet 方法
  49. // 将 targetDataSources 数据 填充到 resolvedDataSources 中
  50. // determineCurrentLookupKey 返回的 lookupKey 本质上是在 resolvedDataSources 中查找 dataSource 返回
  51. // 将 defaultTargetDataSource 数据 填充到 resolvedDefaultDataSource 中
  52. // resolvedDataSources 中 查找不到合适的 dataSource 时返回。
  53. super.afterPropertiesSet();
  54. }
  55. @Override
  56. protected Object determineCurrentLookupKey() {
  57. return data_source_name.get();
  58. }
  59. public void setDb_tb_name(String dataSourceName) {
  60. data_source_name.set(dataSourceName);
  61. }
  62. public void clearDb_tb_name() {
  63. data_source_name.remove();
  64. }
  65. }

MonkeyDO

  1. package center.leon.oak.druid.abstract_routing_data_source.dto;
  2. import com.baomidou.mybatisplus.annotation.TableName;
  3. import lombok.Data;
  4. import lombok.experimental.Accessors;
  5. /**
  6. * @program: leon
  7. * @description:
  8. * @author: Leon
  9. * @create: 2021-07-22 12:05
  10. **/
  11. @Data
  12. @TableName(value = "monkey")
  13. @Accessors(chain = true)
  14. public class MonkeyDO {
  15. private Long id;
  16. private String name;
  17. private Long version;
  18. }

MonkeyMapper

  1. package center.leon.oak.druid.abstract_routing_data_source.mapper;
  2. import center.leon.oak.druid.abstract_routing_data_source.dto.MonkeyDO;
  3. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  4. import org.apache.ibatis.annotations.Mapper;
  5. /**
  6. * @program: leon
  7. * @description:
  8. * @author: Leon
  9. * @create: 2021-07-22 12:04
  10. **/
  11. @Mapper
  12. public interface MonkeyMapper extends BaseMapper<MonkeyDO> {
  13. }

MonkeyService

  1. package center.leon.oak.druid.abstract_routing_data_source.service;
  2. import center.leon.oak.druid.abstract_routing_data_source.dto.MonkeyDO;
  3. /**
  4. * @program: leon
  5. * @description:
  6. * @author: Leon
  7. * @create: 2021-07-22 12:00
  8. **/
  9. public interface MonkeyService {
  10. MonkeyDO get(Long id);
  11. MonkeyDO getInDataSource(Long id, String dataSourceName);
  12. }

MonkeyServiceImpl

  1. package center.leon.oak.druid.abstract_routing_data_source.service.impl;
  2. import center.leon.oak.druid.abstract_routing_data_source.config.MultipleDataSource;
  3. import center.leon.oak.druid.abstract_routing_data_source.dto.MonkeyDO;
  4. import center.leon.oak.druid.abstract_routing_data_source.mapper.MonkeyMapper;
  5. import center.leon.oak.druid.abstract_routing_data_source.service.MonkeyService;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.stereotype.Service;
  8. /**
  9. * @program: leon
  10. * @description:
  11. * @author: Leon
  12. * @create: 2021-07-22 12:03
  13. **/
  14. @Service
  15. public class MonkeyServiceImpl implements MonkeyService {
  16. @Autowired
  17. private MonkeyMapper monkeyMapper;
  18. @Autowired
  19. private MultipleDataSource multipleDataSource;
  20. @Override
  21. public MonkeyDO get(Long id) {
  22. return monkeyMapper.selectById(id);
  23. }
  24. @Override
  25. public MonkeyDO getInDataSource(Long id, String dataSourceName) {
  26. try {
  27. multipleDataSource.setDb_tb_name(dataSourceName);
  28. return monkeyMapper.selectById(id);
  29. } finally {
  30. multipleDataSource.clearDb_tb_name();
  31. }
  32. }
  33. }

PrintMonkey

  1. package center.leon.oak.druid.abstract_routing_data_source.task;
  2. import center.leon.oak.druid.abstract_routing_data_source.dto.MonkeyDO;
  3. import center.leon.oak.druid.abstract_routing_data_source.service.MonkeyService;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.scheduling.annotation.Scheduled;
  7. import org.springframework.stereotype.Component;
  8. /**
  9. * @program: leon
  10. * @description:
  11. * @author: Leon
  12. * @create: 2021-07-22 21:28
  13. **/
  14. @Slf4j
  15. @Component
  16. public class PrintMonkey {
  17. @Autowired
  18. private MonkeyService monkeyService;
  19. @Scheduled(fixedRate = 6 * 1000)
  20. public void printMonkey_localhost() {
  21. MonkeyDO monkeyDO = monkeyService.getInDataSource(1L, "localhost");
  22. log.info("threadName : {}, monkey : {}", Thread.currentThread().getName(), monkeyDO);
  23. }
  24. @Scheduled(fixedRate = 6 * 1000)
  25. public void printMonkey_www_leon_center() {
  26. MonkeyDO monkeyDO = monkeyService.getInDataSource(1L, "www_leon_center");
  27. log.info("threadName : {}, monkey : {}", Thread.currentThread().getName(), monkeyDO);
  28. }
  29. }

application-druid.properties

  1. spring.datasource.type=center.leon.oak.druid.abstract_routing_data_source.config.MultipleDataSource
  2. spring.datasource.leon.data-source-leon-list[0].data-source-name=localhost
  3. spring.datasource.leon.data-source-leon-list[0].driver-class-name=com.mysql.cj.jdbc.Driver
  4. spring.datasource.leon.data-source-leon-list[0].url=jdbc:mysql://localhost:3306/zoo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false
  5. spring.datasource.leon.data-source-leon-list[0].username=root
  6. spring.datasource.leon.data-source-leon-list[0].password=Liang123,
  7. spring.datasource.leon.data-source-leon-list[1].data-source-name=www_leon_center
  8. spring.datasource.leon.data-source-leon-list[1].driver-class-name=com.mysql.cj.jdbc.Driver
  9. 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
  10. spring.datasource.leon.data-source-leon-list[1].username=lmy
  11. spring.datasource.leon.data-source-leon-list[1].password=Lmy123456,
  12. spring.task.scheduling.pool.size=2

AbstractRoutingDataSourceApplication

  1. package center.leon.oak.druid.abstract_routing_data_source;
  2. import center.leon.oak.druid.abstract_routing_data_source.config.MultipleDataSource;
  3. import center.leon.oak.druid.abstract_routing_data_source.dto.MonkeyDO;
  4. import center.leon.oak.druid.abstract_routing_data_source.properties.DataSourceLeonProperties;
  5. import center.leon.oak.druid.abstract_routing_data_source.service.MonkeyService;
  6. import center.leon.oak.druid.abstract_routing_data_source.service.impl.MonkeyServiceImpl;
  7. import lombok.extern.slf4j.Slf4j;
  8. import org.springframework.boot.SpringApplication;
  9. import org.springframework.boot.autoconfigure.SpringBootApplication;
  10. import org.springframework.boot.context.properties.EnableConfigurationProperties;
  11. import org.springframework.context.ConfigurableApplicationContext;
  12. import org.springframework.scheduling.annotation.EnableScheduling;
  13. /**
  14. * @program: leon
  15. * @description:
  16. * @author: Leon
  17. * @create: 2021-07-22 11:28
  18. **/
  19. @Slf4j
  20. @EnableScheduling
  21. @EnableConfigurationProperties
  22. @SpringBootApplication
  23. public class AbstractRoutingDataSourceApplication {
  24. public static void main(String[] args) {
  25. ConfigurableApplicationContext run = SpringApplication.run(AbstractRoutingDataSourceApplication.class, args);
  26. DataSourceLeonProperties dataSourceLeonProperties = run.getBean(DataSourceLeonProperties.class);
  27. log.info("dataSourceLeonProperties : {}", dataSourceLeonProperties);
  28. MonkeyService monkeyService = run.getBean(MonkeyServiceImpl.class);
  29. final MultipleDataSource multipleDataSource = run.getBean(MultipleDataSource.class);
  30. multipleDataSource.setDb_tb_name("localhost");
  31. MonkeyDO monkey_1 = monkeyService.get(1L);
  32. log.info("monkey_1 : {}", monkey_1);
  33. multipleDataSource.clearDb_tb_name();
  34. multipleDataSource.setDb_tb_name("www_leon_center");
  35. MonkeyDO monkey_2 = monkeyService.get(1L);
  36. log.info("monkey_2 : {}", monkey_2);
  37. multipleDataSource.clearDb_tb_name();
  38. }
  39. }

Console

  1. 2021-07-22 22:11:39.813 INFO 69282 --- [ main] d.a.AbstractRoutingDataSourceApplication : show Time ...
  2. 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,)])
  3. 2021-07-22 22:11:39.864 INFO 69282 --- [ scheduling-2] com.alibaba.druid.pool.DruidDataSource : {dataSource-2} inited
  4. 2021-07-22 22:11:39.864 INFO 69282 --- [ main] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited
  5. 2021-07-22 22:11:40.026 INFO 69282 --- [ main] d.a.AbstractRoutingDataSourceApplication : monkey_1 : MonkeyDO(id=1, name=write, version=2)
  6. 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)
  7. 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)
  8. 2021-07-22 22:11:40.075 INFO 69282 --- [ main] d.a.AbstractRoutingDataSourceApplication : monkey_2 : MonkeyDO(id=1, name=monkey sun, version=500)
  9. 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'
  10. 2021-07-22 22:11:40.367 INFO 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
  11. 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
  12. 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
  13. 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
  14. 2021-07-22 22:11:40.368 TRACE 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet : Detected DefaultRequestToViewNameTranslator
  15. 2021-07-22 22:11:40.369 TRACE 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet : Detected SessionFlashMapManager
  16. 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
  17. 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
  18. 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)
  19. 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)
  20. 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)
  21. 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)
  22. 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)
  23. 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)
  24. 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)
  25. 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)
  26. 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)
  27. 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)
  28. 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)
  29. 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)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/52374?site
推荐阅读
相关标签
  

闽ICP备14008679号