Spring ContextLoaderListener vs. DispatcherServlet

In Spring MVC configuration, we must have seen two declarations in web.xml file i.e. ContextLoaderListener and DispatcherServlet. Let’s try to understand their purpose in the framework and their differences.

1. Understanding the Root and Child Contexts

Before reading further, please understand that –

  • Spring can have multiple contexts at a time. One of them will be the root context, and all other contexts will be the child contexts.
  • All child contexts can access the beans defined in the root context, but the opposite is not true. Root context cannot access child context beans.

2. DispatcherServlet is Child Application Context

DispatcherServlet is essentially a Servlet (it extends HttpServlet) whose primary purpose is to handle incoming web requests matching the configured URL pattern. It takes an incoming URI and finds the right combination of controller and view. So it is the front controller.

When you define a DispatcherServlet in spring configuration, you provide an XML file with entries of controller classes, views mappings etc. using contextConfigLocation attribute.

<servlet>
  <servlet-name>employee-services</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:employee-services-servlet.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

If you do not provide a configuration file then it will load its own configuration file using [servlet_name]-servlet.xml. Web applications can define any number of DispatcherServlet entries. Each servlet will operate in its namespace, loading its application context with mappings, handlers, etc.

It means that each DispatcherServlet has access to the web application context. Until specified, each DispatcherServlet creates its own internal web application context.

Starting Spring 3.x, method DispatcherServlet(WebApplicationContext webApplicationContext) create a new DispatcherServlet with the given web application context. It is possible only in Servlet 3.x environment through the ServletContext.addServlet(java.lang.String, java.lang.String) API support.

3. ContextLoaderListener creates the Root Application Context

The ContextLoaderListener creates the root application context and will be shared with child contexts created by all DispatcherServlet contexts. You can have only one entry of ContextLoaderListener in web.xml, but multiple entries of DispatcherServlets.

<listener>
  <listener-class>
    org.springframework.web.context.ContextLoaderListener
  </listener-class>
</listener>
  
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/spring/applicationContext.xml</param-value>
</context-param>

The context of ContextLoaderListener contains beans that globally visible, like services, repositories, infrastructure beans, etc. After the root application context is created, it’s stored in ServletContext as an attribute, the name is:

servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
 
//Where attibute is defined in /org/springframework/web/context/WebApplicationContext.java as
 
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";

To get root application context in Spring controller, you can use WebApplicationContextUtils class.

@Autowired
ServletContext context; 
 
ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(context);
 
if(ac == null){
  return "root application context is null";
}  

4. Difference between ContextLoaderListener and DispatcherServlet

The below image describes the whole relation in a single view.

ContextLoaderListener vs DispatcherServlet
  • ContextLoaderListener creates root application context.
  • DispatcherServlet entries create one child application context per servlet entry.
  • Child contexts can access beans defined in root context.
  • Beans in root context cannot access beans in child contexts (directly).
  • All contexts are added to ServletContext.
  • You can access root context using WebApplicationContextUtils class.

5. Summary

Generally, you will define all MVC related beans (controller and views etc) in DispatcherServlet context, and all cross-cutting beans such as security, transaction, services etc. at root context by ContextLoaderListener.

Generally, this setup works fine because rarely you will need to access any MVC bean (from child context) into security related class (from root context). Mostly we use security beans on MVC classes, and they can access it with above setup.

Happy Learning !!

Comments

Subscribe
Notify of
guest
2 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode