Вы уже нашли лучший способ выполнить эту задачу, я имею в виду AbstractRoutingDataSource
. Если у вас фиксированное количество пользователей, это самый простой способ, которым вы могли бы воспользоваться следующим подходом:
public final class RoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return UserContextHolder.getUserName() + "DataSource";
}
}
И конфигурация:
@Bean
@Qualifier("user1DataSource")
public DataSource userOneDataSource() {
return DataSourceBuilder.create()
.username("user1")
.password("pass")
...
.build();
}
@Bean
@Qualifier("user2DataSource")
public DataSource userOneDataSource() {
return DataSourceBuilder.create()
.username("user2")
...
.build();
}
@Bean
@Primary
public RoutingDataSource dataSource(Map<String, DataSource> datasources) {
return new RoutingDataSource().dataSource(datasources);
}
Если вам нужно добавить пользователей и источники данных во время выполнения, вы можетеиспользуйте что-нибудь вроде этого:
public final class RoutingDataSource extends AbstractRoutingDataSource {
private final ConcurrentHashMap<String, DataSource> dynamicDataSources = new ConcurrentHashMap<>();
@Override
protected Object determineCurrentLookupKey() {
return UserContextHolder.getUserName() + "_datasource";
}
@Override
protected DataSource determineTargetDataSource() {
String currentLookupKey = this.determineCurrentLookupKey().toString();
String userName = UserContextHolder.getUserName();
String password = UserContextHolder.getPassword();
return this.dynamicDataSources.computeIfAbsent(currentLookupKey, (key) -> DataSourceBuilder.create()
.driverClassName("your.driver.class")
.url("jdbc:same:url/here")
.username(userName)
.password(password)
.build());
}
}