Der er en del måder at flå katten på her. Det hele handler i bund og grund om, på hvilket niveau du ønsker at anvende lejemålet.
Grundlæggende
Den grundlæggende tilgang er at binde en eller anden form for nøgle, der identificerer kunden på en per-thread-basis, så du kan finde ud af om kunden, den aktuelle udførelsestråd omhandler. Dette opnås normalt ved at udfylde en ThreadLocal
med nogle godkendelsesrelaterede oplysninger, da du normalt kan udlede lejeren fra den loggede bruger.
Hvis det nu er på plads, er der et par muligheder for, hvor man kan anvende lejerviden. Lad mig kort skitsere de mest almindelige:
Multi-lejemål på databaseniveau
En måde at adskille data for flere klienter på er at have individuelle databaser pr. lejer. Spring Data MongoDBs kerneabstraktion for dette er MongoDBFactory
interface. Den nemmeste måde her er at tilsidesætte SimpleMongoDbFactory.getDb(String name)
og kald den overordnede metode med databasenavnet f.eks. beriget med lejerpræfikset eller lignende.
Flerejemål på samlingsniveau
En anden mulighed er at have lejerspecifikke samlinger, f.eks. gennem lejer pre- eller postfixes. Denne mekanisme kan faktisk udnyttes ved at bruge Spring Expression-sproget (SpEl) i @Document
annotations collectionName
attribut. Først skal du blotlægge lejerpræfikset gennem en springbønne:
@Component("tenantProvider")
public class TenantProvider {
public String getTenantId() {
// … implement ThreadLocal lookup here
}
}
Brug derefter SpEL i dine domænetyper @Document
kortlægning:
@Document(collectionName = "#{tenantProvider.getTenantId()}_accounts"
public class Account { … }
SpEl giver dig mulighed for at henvise til Spring bønner ved navn og udføre metoder på dem. MongoTemplate
(og dermed repository-abstraktionen transitivt) vil bruge kortlægningsmetadataene for dokumentklassen, og kortlægningsundersystemet vil evaluere collectionName
attribut for at finde ud af den samling, der skal interageres med.