Spring Boot and Application Context Hierarchy
Spring Boot supports a simple way of specifying a Spring application context hierarchy.
This post is simply demonstrating this feature, I am yet to find a good use of it in the projects I have worked on. Spring Cloud uses this feature for creating a bootstrap context where properties are loaded up, if required, from an external configuration server which is made available to the main application context later on.
To quickly take a step back – a Spring Application Context manages the lifecycle of all the beans registered with it. Application Context hierarchies provide a way to reuse beans, beans defined in the parent context is accessible in the child contexts.
Consider a contrived use-case of using multiple application contexts and application context hierarchy – this is to provide two different ports with different set of endpoints at each of these ports.
Child1 and Child2 are typical Spring Boot Applications, along these lines:
package child1; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.PropertySource; import root.RootBean; @SpringBootApplication @PropertySource("classpath:/child1.properties") public class ChildContext1 { @Bean public ChildBean1 childBean(RootBean rootBean, @Value("${root.property}") String someProperty) { return new ChildBean1(rootBean, someProperty); } }
Each of the application resides in its own root package to avoid collisions when scanning for beans. Note that the bean in the child contexts depend on a bean that is expected to come from the root context.
The port to listen on is provided as properties, since the two contexts are expected to listen on different ports I have explicitly specified the property file to load with a content along these lines:
server.port=8080 spring.application.name=child1
Given this set-up, Spring Boot provides a fluid interface to load up the root context and the two child contexts:
SpringApplicationBuilder appBuilder = new SpringApplicationBuilder() .parent(RootContext.class) .child(ChildContext1.class) .sibling(ChildContext2.class); ConfigurableApplicationContext applicationContext = appBuilder.run();
The application context returned by the SpringBootApplicationBuilder appears to be the final one in the chain, defined via ChildContext2 above.
If the application is now started up, there would be a root context with two different child contexts each exposing an endpoint via a different port. A visualization via the /beans actuator endpoint shows this:
Not everything is clean though, there are errors displayed in the console related to exporting jmx endpoints, however these are informational and don’t appear to affect the start-up.
Samples are available in my github repo
Reference: | Spring Boot and Application Context Hierarchy from our JCG partner Biju Kunjummen at the all and sundry blog. |