com.gitlab.spacetrucker.modularspringcontexts.module.ModularSpringContextsModuleBean Maven / Gradle / Ivy
package com.gitlab.spacetrucker.modularspringcontexts.module;
import java.util.List;
import java.util.concurrent.Executor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.xml.NamespaceHandlerResolver;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.AbstractXmlApplicationContext;
/**
* This implementation is used to represent a module. A module is merely a
* spring application context. It has support for a custom
* {@link NamespaceHandlerResolver} to allow extensible XML authoring of spring
* beans schema. The actual startup is done via a {@link #moduleStarter} to
* allow parallel module startup. This module can depend upon a number of
* predefined modules. Bean imports are possible from these modules.
*
* The {@code module} element of {@code modular-spring-contexts.xsd} will cause
* an initialization of an instance of this type.
*/
public class ModularSpringContextsModuleBean extends AbstractXmlApplicationContext implements ApplicationContextAware {
private NamespaceHandlerResolver customNamespaceHandlerResolver;
private List requiredModules;
private Executor moduleStarter = new SameThreadExecutor();
private ApplicationContext moduleHost;
@Override
protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
super.initBeanDefinitionReader(reader);
reader.setNamespaceHandlerResolver(customNamespaceHandlerResolver);
}
public void setCustomNamespaceHandlerResolver(NamespaceHandlerResolver customNamespaceHandlerResolver) {
this.customNamespaceHandlerResolver = customNamespaceHandlerResolver;
}
public void setRequiredModules(List requiredModules) {
this.requiredModules = requiredModules;
}
public void setModuleStarter(Executor moduleStarter) {
this.moduleStarter = moduleStarter;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.moduleHost = applicationContext;
}
/**
* Adds the modules this module depends upon as singleton beans to the bean
* factory of this application context.
*/
@Override
protected void onRefresh() throws BeansException {
super.onRefresh();
for (String requiredModule : requiredModules) {
if (getBeanFactory().containsBeanDefinition(requiredModule)) {
throw new IllegalStateException(
"The name of module " + requiredModule + " is already registered as a bean definition.");
}
getBeanFactory().registerSingleton(requiredModule,
moduleHost.getBean(requiredModule, ApplicationContext.class));
}
}
@Override
public void afterPropertiesSet() {
if (!isActive()) {
moduleStarter.execute(new Runnable() {
@Override
public void run() {
refresh();
}
});
}
}
}