Alterar o esquema do banco de dados durante o tempo de execução com base no usuário conectado

Eu li muitas perguntas e respostas sobre o roteamento dinâmico de fontes de dados e implementei uma solução usandoAbstractRoutingDataSource e outro (veja abaixo). Tudo bem, mas requer propriedades codificadas para todas as fontes de dados. À medida que o número de usuários que usam o aplicativo aumenta, essa não é mais uma maneira adequada de rotear. Também seria necessário adicionar uma entrada às propriedades toda vez que um novo usuário se registrasse. A situação é a seguinte

1 servidor de banco de dadosEm muitos esquemas nesse servidor, todo usuário tem seu próprio esquema.Eu só preciso alterar o nome do esquema durante o tempo de execuçãoo nome do esquema pode ser retido pelo usuário conectado

estou a usarspring boot 1.4.0 junto comhibernate 5.1 espring data jpa

Não consigo encontrar uma maneira de mudar o esquema, de forma totalmente dinâmica. Alguém sabe como fazer isso na primavera?

EDITAR:

Graças à resposta de @Johannes Leimer, eu consegui uma implementação eficiente.

Aqui está o código:

Fornecedor de Usuários:

@Component
public class UserDetailsProvider {
    @Bean
    @Scope("prototype")
    public CustomUserDetails customUserDetails() {
        return (CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    }
}

UserSchemaAwareRoutingDatasource:

public class UserSchemaAwareRoutingDataSource extends AbstractDataSource {
@Inject
Provider<CustomUserDetails> customUserDetails;

@Inject
Environment env;
private LoadingCache<String, DataSource> dataSources = createCache();

@Override
public Connection getConnection() throws SQLException {
    try {
        return determineTargetDataSource().getConnection();
    } catch (ExecutionException e){
        e.printStackTrace();

        return null;
    }
}

@Override
public Connection getConnection(String username, String password) throws SQLException {
    System.out.println("getConnection" + username);
    System.out.println("getConnection2" + password);
    try {
        return determineTargetDataSource().getConnection(username, password);
    } catch (ExecutionException e) {
        e.printStackTrace();
        return null;
    }
}

private DataSource determineTargetDataSource() throws SQLException, ExecutionException {
    try {
        String schema = customUserDetails.get().getUserDatabase();
        return dataSources.get(schema);
    } catch (NullPointerException e) {
        e.printStackTrace();

        return dataSources.get("fooooo");
    }

}

questionAnswers(2)

yourAnswerToTheQuestion