Replies: 1 comment
-
I still hesitate to create a pull request as there are no reactions to this idea. Maybe some feedback from the core committers ? It should be easy to do, e.g. this would do the trick @Component
@ComponentScan(
excludeFilters = {@Filter(type = FilterType.CUSTOM, classes = ApplicationModuleFilter.class)})
public class ApplicationModuleFilter implements TypeFilter {
private static final String ACTIVE_APPLICATION_MODULES_PROPERTY_NAME =
"spring-modulith.active-application-modules";
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private Set<String> beanTypesToFilter = null;
private final Environment environment;
public ApplicationModuleFilter(Environment environment) {
this.environment = environment;
}
private Set<String> resolveFullyQualifiedClassNamesOfSpringBeansToFilter() {
var moduleIdentifiersToLoad = new HashSet<String>();
var activeModuleIdentifiers = environment.getProperty(ACTIVE_APPLICATION_MODULES_PROPERTY_NAME);
if (activeModuleIdentifiers != null && !activeModuleIdentifiers.isBlank()) {
Arrays.stream(activeModuleIdentifiers.split(","))
.forEach(moduleIdentifier -> moduleIdentifiersToLoad.add(moduleIdentifier.trim()));
} else {
logger.info(
"No modules to load specified in {}. Loading all modules by default.", ACTIVE_APPLICATION_MODULES_PROPERTY_NAME);
return Set.of();
}
var modules = ApplicationModules.of(Application.class);
var applicationModulesToLoad = new TreeSet<ApplicationModule>();
for (String moduleIdentifier : moduleIdentifiersToLoad) {
var module = modules.getModuleByName(moduleIdentifier);
if (module.isEmpty()) {
var availableModuleIdentifiers =
modules.stream()
.map(ApplicationModule::getIdentifier)
.map(ApplicationModuleIdentifier::toString)
.toList();
throw new IllegalStateException(
String.format(
"Module %s not found. Available module identifiers: %s",
moduleIdentifier, availableModuleIdentifiers));
}
applicationModulesToLoad.add(module.get());
module.get().getDependencies(modules, DependencyDepth.ALL).stream()
.map(ApplicationModuleDependency::getTargetModule)
.forEach(m -> applicationModulesToLoad.add(m));
}
logger.info(
"Loading application modules: {}",
applicationModulesToLoad.stream()
.map(ApplicationModule::getIdentifier)
.map(ApplicationModuleIdentifier::toString)
.toList());
return modules.stream()
.filter(m -> !applicationModulesToLoad.contains(m))
.flatMap(m -> m.getSpringBeans().stream())
.map(SpringBean::getFullyQualifiedTypeName)
.collect(Collectors.toSet());
}
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
if (beanTypesToFilter == null)
beanTypesToFilter = resolveFullyQualifiedClassNamesOfSpringBeansToFilter();
if (beanTypesToFilter.contains(metadataReader.getClassMetadata().getClassName())) {
logger.debug(
"Filtering bean {} as it is not part of the application modules to load",
metadataReader.getClassMetadata().getClassName());
return false;
}
return true;
}
}``` |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
It would be beneficial to keep source code for many application modules in once place, but then deploy the built container multiple times with only selected application modules being loaded in a each deployed instance.
This allows to develop in kind of a monolithic, but well structured way and at the same time deploy in a more microservice oriented fashion, which allows to reap e.g. the benefits of easily scaling some parts of the overall application.
As far as I got from the docs, this is not supported out of the box by Spring Modulith. I've already setup a small prototype that uses Spring Modulith's application modules API to adapt the application context upon startup. It basically just removes all application module provided bean definitions from the application context that are not required based on a list of application modules that should be active in a given instance.
First of all I ask myself the question if this is the proper way to go ? Additionally, I ask myself the question if this isn't a useful feature which should be added to Spring Modulith ?
Beta Was this translation helpful? Give feedback.
All reactions