Há algumas maneiras de esfolar o gato aqui. Basicamente, tudo se resume a qual nível você gostaria de aplicar a locação.
Noções básicas
A abordagem básica é vincular algum tipo de chave identificando o cliente por thread, para que você possa descobrir sobre o cliente com o qual o thread de execução atual lida. Isso geralmente é feito preenchendo um
ThreadLocal
com algumas informações relacionadas à autenticação, pois normalmente você pode derivar o locatário do usuário conectado. Agora, se isso estiver em vigor, há algumas opções de onde aplicar o conhecimento do locatário. Deixe-me descrever brevemente os mais comuns:
Multi-tenancy no nível do banco de dados
Uma maneira de separar dados para vários clientes é ter bancos de dados individuais por locatário. A abstração principal do Spring Data MongoDB para isso é o
MongoDBFactory
interface. A maneira mais fácil aqui é substituir SimpleMongoDbFactory.getDb(String name)
e chame o método pai com o nome do banco de dados, por exemplo enriquecido pelo prefixo de inquilino ou similar. Multi-locação no nível de cobrança
Outra opção é ter coleções específicas de inquilinos, por exemplo. através de pré ou pós-fixos de inquilino. Esse mecanismo pode realmente ser aproveitado usando a linguagem Spring Expression (SpEl) no
@Document
collectionName
da anotação atributo. Primeiro, exponha o prefixo do locatário por meio de um bean Spring: @Component("tenantProvider")
public class TenantProvider {
public String getTenantId() {
// … implement ThreadLocal lookup here
}
}
Em seguida, use SpEL em seus tipos de domínio
@Document
mapeamento: @Document(collectionName = "#{tenantProvider.getTenantId()}_accounts"
public class Account { … }
SpEl permite que você faça referência aos beans Spring pelo nome e execute métodos neles.
MongoTemplate
(e, portanto, a abstração do repositório de forma transitiva) usará os metadados de mapeamento da classe do documento e o subsistema de mapeamento avaliará o collectionName
atributo para saber mais sobre a coleção com a qual interagir.