如何使用SpringBoot创建动态数据源

时间:2016-11-28 18:10:14

标签: spring spring-boot spring-data datasource spring-data-jpa

我有一个springboot应用程序,它自己的数据源(让我们调用DB1)设置在属性上工作正常。

但是这个应用程序需要使用用户之前通知并存储在DB1中的一些参数来配置 new 数据源(DB2)。

我的想法是创建一个命名bean,因此我的应用程序的特定部分可以用来访问DB2表。我认为可以通过重新启动应用程序来实现,但我想避免它。

此外,我需要我的代码的某些部分使用新的数据源(spring数据jpa,映射等)。我不知道是不是这件事,但它是一个Web应用程序,所以我不能只为请求线程创建数据源。

你能帮助我吗?

提前致谢。

1 个答案:

答案 0 :(得分:1)

Spring具有动态数据源路由,如果您正在前进的话。在我的例子中,它是相同的模式(WR / RO)

public class RoutingDataSource extends AbstractRoutingDataSource {

  @Autowired
  private DataSourceConfig dataSourceConfig;

  @Override
  protected Object determineCurrentLookupKey() {
    return DbContextHolder.getDbType();
  }

  public enum DbType {
    MASTER, WRITE, READONLY,  
  }

然后你需要一个自定义注释和一个方面

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ReadOnlyConnection {
}

@Aspect 
@Component
@Order(1)
public class ReadOnlyConnectionInterceptor {

  Pointcut(value = "execution(public * *(..))")
  public void anyPublicMethod() {}

  @Around("@annotation(readOnlyConnection)")
  public Object proceed(ProceedingJoinPoint proceedingJoinPoint, ReadOnlyConnection readOnlyConnection) throws Throwable           {
    Object result = null;
    try {
      DbContextHolder.setDbType(DbType.READONLY);
      result = proceedingJoinPoint.proceed();
      DbContextHolder.clearDbType();
      return result;
    } finally {
      DbContextHolder.clearDbType();
    }
  }
}

然后你可以使用标签@ReadOnlyConnection

对你的DB采取行动
@Override
@Transactional(readOnly = true)
@ReadOnlyConnection
public UnitDTO getUnitById(Long id) {
  return unitRepository.findOne(id);
}

可在此处找到一个示例:https://github.com/afedulov/routing-data-source

我使用它作为我工作的基础,虽然它仍在进行中,因为我仍然需要解决运行时依赖性(即休眠分片)。