Cambiar el esquema de la base de datos durante el tiempo de ejecución en función del usuario conectado

He leído muchas preguntas y respuestas sobre el enrutamiento dinámico de la fuente de datos y he implementado una solución usandoAbstractRoutingDataSource y otro (ver abajo). Eso está bien, pero requiere propiedades codificadas para todas las fuentes de datos. A medida que aumenta el número de usuarios que usan la aplicación, esta ya no es una forma adecuada de enrutamiento. También requeriría agregar una entrada a las propiedades cada vez que un nuevo usuario se registre. La situación es la siguiente.

1 servidor de base de datosMuchos esquemas en ese servidor, cada usuario tiene su propio esquema.Solo necesito cambiar el nombre del esquema durante el tiempo de ejecuciónel nombre de esquema puede ser retenido por el usuario conectado

Estoy usandospring boot 1.4.0 Juntos conhibernate 5.1 yspring data jpa

No puedo encontrar una manera de cambiar el esquema, de forma completamente dinámica. ¿Alguien sabe cómo hacerlo en primavera?

EDITAR:

Gracias a la respuesta de @Johannes Leimer, obtuve una implementación funcional.

Aquí está el código:

Proveedor de usuario:

@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");
    }

}

Respuestas a la pregunta(2)

Su respuesta a la pregunta