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:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | 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:
1 2 | 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:
1 2 3 4 5 6 7 | 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. |
Why the errors in JMX endpoints are coming , did you investigate.