Johannes Dorn Johannes Dorn - 6 months ago 16
Java Question

How do i eagerly initialize beans per tenant?

I'm trying to write a multi-tenant Spring Boot application but having trouble to eager initialize beans when the server starts (i.e. not lazily once the tenant requests the bean)

To support multi-tenancy, i created a

@CustomerScoped
annotation that creates objects based on a ThreadLocal String value.

My configuration provides a bean like this and lazily initializes it:

@Autowired
private AutowireCapableBeanFactory beanFactory;

@Bean
@CustomerScoped
public Scheduler getScheduler() {
CreateDefaults job = factory.createBean(CreateDefaults.class));
Scheduler scheduler = new Scheduler();
scheduler.schedule(job);
return scheduler;
}

@PostConstruct
public void init() {
CustomerScope.setCustomer("tenant1");
getScheduler();
CustomerScope.setCustomer("tenant2");
getScheduler();
CustomerScope.clearCustomer();
}


When starting the server, two Schedulers should be created, each of which would execute their own instance of "Create Defaults".
When tenants access the application themselves, they should be getting their own instance of this Scheduler.
This seems to work but i wonder whether this is the correct way of doing things.
In particular, i am worried about the fact that the beanFactory isn't scoped itself.

Would this approach work and scale for more complex systems?

Answer

My code sample was actually correct. The Beanfactory doesn't need to be scoped itself, it just has to be made aware of the scope, which in my case can be achieved in the configuration:

@Bean 
public static CustomScopeConfigurer customScope() {
    CustomScopeConfigurer configurer = new CustomScopeConfigurer();
    configurer.addScope(CustomerScope.CUSTOMER_SCOPE_NAME, new CustomerScope()); 
    return configurer;
}
Comments