This week's book giveaway is in the OCPJP forum. We're giving away four copies of OCA/OCP Java SE 7 Programmer I & II Study Guide and have Kathy Sierra & Bert Bates on-line! See this thread for details.
Trying to put an MVC project together and using the latest STS plugin to Eclipse, I thought that I could put the <context:component-scan> (also <context:annotation-config>) statements in the servlet-context.xml file that corresponds to the particular servlet that would use DI for a bean. But it never found the bean to inject.
When I moved the statements to the root-context.xml file then it found the bean and injected it as expected.
Now I've also seen 'app-context.xml' for a Hibernate utility project put into the META-INF/spring directory which contains DB-related info.
So what I'm looking for is a definition of the order of processing of XML files to resolve DI issues as well as the difference of such files as app-context.xml vs. root-context.xml.
I've read through section 4 of the Spring framework docs, but didn't see anything to address these questions.
The docs definitely address it in the form of a diagram relating to Parent-Child applicationContexts.
So the root-context.xml is read in by the ContextLoaderListener which creates a parent ApplicationContext for the web. This is first.
Then the DispatcherServlet creates a child ApplicationContext which reads in the servlet-context.xml. This is second. Child ApplicationContexts can see all the beans in the parent, but the Parent cannot see any beans in the child.
So when you moved the bean definition into the parent, other beans of the parent could now get them DI'd into them. Where when that bean was in the child, not parent bean could get the child bean injected into them.
Thanks for the info. I'm looking for the diagram to review.
But what I don't understand is that if I put the <context> lines in the servlet-context.xml file for the servlet that was requesting the injection of the bean, why would it not make the bean part of the child context and thus unavailable to other parts of the application?
Does the app-context.xml in the META-INF directory fall into the same category as the servlet-context.xml?
Joined: Sep 19, 2012
What I left out yesterday from my original posting is that the test I was working on had 2 servlets in it, each with their own DispatcherServlet configuration. I was doing this to not have to specify a URL pattern in the web.xml file so that each servlet could handle a different mapping based on RequestMapping settings.
By trying to autowire a bean in servlet 1 and not in servlet 2, I was getting an error about not being able to autowire the bean in servlet 2 - even though I hadn't put it into servlet 2. I included it for component scanning in servlet 1's context file for the bean to be autowired.
In my web.xml file I used the same url-pattern, '/', for both servlets. As soon as I changed the pattern for the 2nd servlet to anything other than / or /* it worked fine. The RequestMapping in servlet 2 took care of the mapping I wanted.
If I put the bean to be autowired in the root context file I could put the url-pattern back to '/' for both servlets.
So can someone explain what was happening? Is there a bug here or is this behavior 'normal'? The fact that I could change the url-pattern for both servlets to '/' when the bean to be autowired is included in the roo† context still seems strange.
I don't understand why you would want two separate DispatcherServlets in one web application.
The only time you might do that is one for your web app and a MessageDispatcherServlet for SOAP based Web Services.
Always think about availability of ApplicationContexts and who can see what.
If you have two DispatcherServlets, I actually think one AppContext would replace/overwrite the other when it puts it into the ServletContext under its name. Since they would have the same name, and I assume ServletContext store it as a Map, and you can't put two different keys into the same map.
child beans can only see parent beans. So a parent bean can be injected into a child. But a child bean cannot be injected into a parent bean.
But in the two DispatcherServlet case, those are two separate ApplicationContexts that know nothing about each other.
Joined: Sep 19, 2012
What I want to be able to do is to have multiple controllers, each responsible for different functionality. I recognize that the servlet contexts would not see each other's environment, but they could share the common one from the parent.
Since I'm new to this, I don't claim that this is the best way to accomplish this, but in trying this I came across what I thought was strange behavior. Could you provide a different approach for what I'm trying to accomplish? In doing some "big dumb searches" (google), I haven't come across much that deals with multiple controllers. I would see this as advantageous for handling REST calls.
Any direction/clarification you could provide would be appreciated.
You are using @RequestMapping correct? That is where the URL parts go.
1) DispatcherServlet with servlet mapping to basically "*", not exactly that but mapped to all URL for your application.
Then create as many Controller classes as you want and annotate the methods/classes with @RequestMapping. Each method mapped to a different URL.
See, now I have 4 different mappings from 2 different Controllers but I would still just have one Dispatcher Servlet deployed. Now my grouping of methods in which POJO controller it went into isn't really well thought out. Account mappings might be in an AccountController and Person mappings in a PersonController, and I might what to have better URLs like all Account mappings start with "/account/thenSomething" Which would allow me to put an @RequestMapping at the class level so @RequestMapping("/account/*") then the last part of the mapping would be on each method.
Joined: Sep 19, 2012
Thank you Mark.
If I wanted to have each controller as you mentioned handle different functionality, using the same basic format, would I do
Using one DispatcherServlet and url-pattern of "*" (or would "/" work?).