Вы можете использовать AbstractRoutingDataSource
для достижения этой цели.Для AbstractRoutingDataSource
требуется информация, чтобы знать, к какому фактическому DataSource
направить маршрут (именуемый Context ), что обеспечивается методом determineCurrentLookupKey()
.Используя пример из здесь .
Определить Контекст , например:
public enum ClientDatabase {
CLIENT_A, CLIENT_B
}
Затем необходимо определить держатель контекста, который будет использоваться в determineCurrentLookupKey()
public class ClientDatabaseContextHolder {
private static ThreadLocal<ClientDatabase> CONTEXT = new ThreadLocal<>();
public static void set(ClientDatabase clientDatabase) {
Assert.notNull(clientDatabase, "clientDatabase cannot be null");
CONTEXT.set(clientDatabase);
}
public static ClientDatabase getClientDatabase() {
return CONTEXT.get();
}
public static void clear() {
CONTEXT.remove();
}
}
Тогдавы можете расширить AbstractRoutingDataSource
, как показано ниже:
public class ClientDataSourceRouter extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return ClientDatabaseContextHolder.getClientDatabase();
}
}
Наконец, DataSource
конфигурация бина:
@Bean
public DataSource clientDatasource() {
Map<Object, Object> targetDataSources = new HashMap<>();
DataSource clientADatasource = clientADatasource();
DataSource clientBDatasource = clientBDatasource();
targetDataSources.put(ClientDatabase.CLIENT_A,
clientADatasource);
targetDataSources.put(ClientDatabase.CLIENT_B,
clientBDatasource);
ClientDataSourceRouter clientRoutingDatasource
= new ClientDataSourceRouter();
clientRoutingDatasource.setTargetDataSources(targetDataSources);
clientRoutingDatasource.setDefaultTargetDataSource(clientADatasource);
return clientRoutingDatasource;
}