Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why DispatcherServlet creates another application context?

Tags:

I have configured the root application context using ContextLoaderListener and the context init-parameter contextConfigLocation.

The root context is then accessed by JSF (*.jsf) variable-resolver. It works fine.

Now the problem is, the requests (*.do) going thru DispatcherServlet will get another application context, and singleton beans are then instantiated twice.

I don't need another application context for DispatcherServlet, how can I specify it to re-use the existing root application context, which is loaded by ContextLoaderListener?

NOTE

After read the reference pages in answers, I know there is a context separation between the root context and the dispatcher context, but none of the references tell me where to go. So here is my solution, maybe helpful for other people facing the similar question:

  1. In the context config XML for the dispatcher servlet: dispatcher-servlet.xml, I have duplicated defined <context:component-scan/> which is already defined in the root context. So remove it. The dispatcher-servlet.xml only have to define those beans used for Spring MVC only.

  2. All the controllers have already been scanned and instantiated in the root context, however, Spring MVC by default doesn't register the controllers in the root context for request mappings. You can either:

    2.1. In the root context, exclude @Controller from <component-scan>, and scan @Controller only in the dispatcher-servlet.xml.

    2.2. Or, set the property DefaultAnnotationHandlerMapping.detectHandlersInAncestorContexts to true:

    (dispatcher-servlet.xml:)  <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">     <property name="detectHandlersInAncestorContexts" value="true" /> </bean> 
like image 962
Xiè Jìléi Avatar asked Oct 20 '11 09:10

Xiè Jìléi


People also ask

Is DispatcherServlet instantiated via an application context?

In short: the DispatcherServlet is not instantiated via an application context. It is instantiated before any application context is created. parent ApplicationContext is creted by ContextLoaderListener , child ApplicationContext is created by Spring MVC DispatcherServlet . It is also called RootApplicationContext.

What is the purpose of DispatcherServlet properties?

The job of the DispatcherServlet is to take an incoming URI and find the right combination of handlers (generally methods on Controller classes) and views (generally JSPs) that combine to form the page or resource that's supposed to be found at that location.

What is the purpose of a web application context?

WebApplicationContext is used to create web applications. ApplicationContext is the parent of the WebApplicationContext interface. WebApplicationContext is the child of the ApplicationContext interface. In the case of ApplicationContext, we have to create and destroy the container objects manually.

Does root context belongs to DispatcherServlet?

Beans/configuraiton loaded by the ContextLoaderListener is the root context, everything loaded by a DispatcherServlet (or MessageDispatcherServlet for Spring-WS) is a child context. You can have multiple servlets which all have access to the root context (should contain shared resources like services, etc.).


2 Answers

To answer your first question, the DispatcherServlet creates a context because that's how it allows itself to be configured, and if you have multiple DispatcherServlets in one app, they'd each need to be configured separately. Therefore each one gets its own context, and each of those contexts is separate from the "root" context, where all of your real, "working" beans should live so they can be shared between the other contexts. There have been a number of questions over the last couple of weeks that were spawned by confusion over this very issue. You might gain a better understanding of how things work by checking out the answers:

Spring XML file configuration hierarchy help/explanation

Declaring Spring Bean in Parent Context vs Child Context

Spring-MVC: What are a "context" and "namespace"?

like image 175
Ryan Stewart Avatar answered Oct 16 '22 11:10

Ryan Stewart


If you have a DispatcherServlet running, there is no need to use ContextLoaderListener. Just use ContextLoader.getCurrentWebApplicationContext() to access the WebApplicationContext.

Just keep the bean definitions separate as outlined in this previous answer.

like image 38
Sean Patrick Floyd Avatar answered Oct 16 '22 11:10

Sean Patrick Floyd