springboot 多数据源配置

Posted 一个小学僧

tags:

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

1、配置类

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * 配置多数据源
 */
@Configuration
public class DynamicDataSourceConfig {

  @Bean
  @ConfigurationProperties("spring.datasource.druid.report")
  public DataSource reportDataSource() {
    return DruidDataSourceBuilder.create().build();
  }
  
  @Bean
  @ConfigurationProperties("spring.datasource.druid.etlengine-v4")
  public DataSource etlengineV4DataSource() {
      return DruidDataSourceBuilder.create().build();
  }
  

  @Bean
  @Primary
  public DynamicDataSource dataSource(DataSource reportDataSource, DataSource etlengineV4DataSource) {
    Map<Object, Object> targetDataSources = new HashMap<>();
    targetDataSources.put(DataSourceNames.REPORT, reportDataSource);
    targetDataSources.put(DataSourceNames.ETLENGINE_V4, etlengineV4DataSource);
    return new DynamicDataSource(reportDataSource, targetDataSources);
  }
}

2、动态数据源

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.Map;

/**
 * 动态数据源
 */
public class DynamicDataSource extends AbstractRoutingDataSource {
  private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

  public DynamicDataSource(DataSource defaultTargetDataSource,
      Map<Object, Object> targetDataSources) {
    super.setDefaultTargetDataSource(defaultTargetDataSource);
    super.setTargetDataSources(targetDataSources);
    super.afterPropertiesSet();
  }

  @Override
  protected Object determineCurrentLookupKey() {
    return getDataSource();
  }

  public static void setDataSource(String dataSource) {
    contextHolder.set(dataSource);
  }

  public static String getDataSource() {
    return contextHolder.get();
  }

  public static void clearDataSource() {
    contextHolder.remove();
  }

}

3、自定义一个注解,并通过aop自定义切面去动态注入不同的数据源

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
  String name() default "";
}
@Aspect
@Component
public class DataSourceAspect implements PriorityOrdered {
  protected Logger logger = LoggerFactory.getLogger(getClass());

  @Pointcut("@annotation(com.patrick.datasources.annotation.DataSource)")
  public void dataSourcePointCut() {

  }

  @Around("dataSourcePointCut()")
  public Object around(ProceedingJoinPoint point) throws Throwable {
    MethodSignature signature = (MethodSignature) point.getSignature();
    Method method = signature.getMethod();

    DataSource ds = method.getAnnotation(DataSource.class);
    if (ds == null) {
      DynamicDataSource.setDataSource(DataSourceNames.REPORT);
      logger.debug("set datasource is " + DataSourceNames.REPORT);
    } else {
      DynamicDataSource.setDataSource(ds.name());
      logger.debug("set datasource is " + ds.name());
    }

    try {
      return point.proceed();
    } finally {
      DynamicDataSource.clearDataSource();
      logger.debug("clean datasource");
    }
  }

  @Override
  public int getOrder() {
    return 1;
  }
}

以上是关于springboot 多数据源配置的主要内容,如果未能解决你的问题,请参考以下文章

springboot之多数据源配置JdbcTemplate

基于springboot的多数据源配置

springboot整合多数据源配置

SpringBoot 的多数据源配置与动态切换

SpringBoot 的多数据源配置与动态切换

SpringBoot 的多数据源配置与动态切换