Given the Spring Boot application, which consists of a bootstrap module and two or more isolated business modules, each of which provides a business domain-specific REST API, and each of which uses an independent isolated document storage to save data, what should I do ? about setting up such an application so that:
- The bootstrap module defines the parent context (not the web) that provides certain shared resources to the base modules (global configuration, object mappers, etc.).
- Each business module provides its REST controllers on the same port, but with a different context path. Ideally, I want to be able to determine the base path for each module (for example, / api / catalog, / api / orders) and separately define a subpath in each controller.
- Each business module defines its own repository configuration (for example, different MongoDB settings for each module)
To isolate the contexts of individual business modules (which allows me to manage independent repository configurations in each module), I tried to use the context hierarchies available in SpringApplicationBuilder to isolate the contexts of each of the individual business modules:
public class Application { @Configuration protected static class ParentContext { } public static void main(String[] args) throws Exception { new SpringApplicationBuilder(ParentContext.class) .child(products.config.ModuleConfiguration.class) .web(true) .sibling(orders.config.ModuleConfiguration.class) .web(true) .run(args); } }
however, since each module contains a configuration class annotated with @EnableAutoConfiguration, this forces Spring Boot to try to run two independent built-in servlet containers, each of which tries to connect to the same port:
@Configuration @EnableAutoConfiguration public class WebApplicationConfiguration { @Value("${api.basePath:/api}") protected String apiBasePath; @Bean public DispatcherServlet dispatcherServlet() { return new DispatcherServlet(); } @Bean public ServletRegistrationBean dispatcherServletRegistration() { ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet(), apiBasePath + "/products/*"); registration.setName(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME); return registration; } }
The Spring Boot documentation on contextual hierarchies says that a parent context cannot be a web context, so I was a bit confused about how to split the built-in servlet container between isolated child contexts.
I created a minimal GitHub project to illustrate this:
source share