Issue
First came into this problem by wondering how I was supposed to autowire/inject a service layer level bean from the ContextLoaderListener's application context INTO a bean from DispatcherServlet's context.
Let's say for a random simple situation, a PuppyService needs to be autowired/injected into PuppyResource on the actual resource/controller level. The Puppy Service along with the Puppy Repository and any Puppy Entities would be beans auto-loaded into the root/ContextLoaderListener's context from a @Configuration class that does a component-scan in some other package to grab the beans and load them...
At the same time, the Puppy RESOURCE would be more on the webMvc level and loaded into DispatcherServlet's context.
From what I just read, and now hopefully understand, the root context is actually the 'parent' context of the context created by DispatcherServlet. This means that beans that live inside the root context can actually be autowired/injected into any bean that lives inside the context created by DispatcherServlet. I literally just learned about this concept of 'nested' contexts. Is this accurate?
If this is accurate, then where does the configuration get set to make the root context the 'parent' context? Currently, when I configure the servlet/listener, I do it via a custom implementation of WebApplicationInitializer, wherein I simply create two contexts, load them each respectively into a DispatcherServlet instance, and a ContextLoaderListener instance, then register each of those respectively into the servlet. I'm guessing somewhere in there, the ContextLoaderListener's application context automatically gets set to the 'parent'.
Could someone briefly explain this? Thank you.
Solution
The behavior is built into the DispatcherServlet
. The javadoc defines the root application context.
Only the root application context as loaded by
ContextLoaderListener
, if any, will be shared.
The javadoc of ContextLoaderListener
also states
Bootstrap listener to start up and shut down Spring's root
WebApplicationContext
.
And, assuming you use the DispatcherServlet
constructor that receives a WebApplicationContext
,
If the given context does not already have a parent, the root application context will be set as the parent.
you'll get this behavior automatically.
Again from the javadoc,
This constructor is useful in Servlet 3.0+ environments where instance-based registration of servlets is possible through the
ServletContext.addServlet(java.lang.String, java.lang.String)
API.
which is what the common AbstractDispatcherServletInitializer
uses to set up your Spring MVC application.
Answered By - Sotirios Delimanolis
Answer Checked By - David Marino (JavaFixing Volunteer)