Role/Purpose of ContextLoaderListener in Spring?
Your understanding is correct. The ApplicationContext
is where your Spring beans live. The purpose of the ContextLoaderListener
is two-fold:
to tie the lifecycle of the
ApplicationContext
to the lifecycle of theServletContext
andto automate the creation of the
ApplicationContext
, so you don't have to write explicit code to do create it - it's a convenience function.
Another convenient thing about the ContextLoaderListener
is that it creates a WebApplicationContext
and provides access to the ServletContext
via ServletContextAware
beans and the getServletContext
method.
What do ContextLoaderListener and RequestContextListener do?
org.springframework.web.context.ContextLoaderListener
is a class from Spring framework. As it implements the ServletContextListener
interface, the servlet container notifies it at startup (contextInitialized
) and at shutdown (contextDestroyed
) of a web application.
It is specifically in charge of bootstrapping (and orderly shutdown) the Spring ApplicationContext.
Ref: javadoc says:
Bootstrap listener to start up and shut down Spring's root WebApplicationContext. Simply delegates to ContextLoader as well as to ContextCleanupListener.
org.springframework.web.context.request.RequestContextListener
is another class from same framework. Its javadoc says:
Servlet 2.4+ listener that exposes the request to the current thread, through both LocaleContextHolder and RequestContextHolder. To be registered as listener in web.xml.
Alternatively, Spring's RequestContextFilter and Spring's DispatcherServlet also expose the same request context to the current thread. In contrast to this listener, advanced options are available there (e.g. "threadContextInheritable").
This listener is mainly for use with third-party servlets, e.g. the JSF FacesServlet. Within Spring's own web support, DispatcherServlet's processing is perfectly sufficient.
So it is normally not used in a Spring MVC application, but allows request or session scoped bean in a JSF application using a Spring ApplicationContext
Spring contextloaderlistener role in bean creation
The ApplicationContext creates the beans utilising a BeanFactory, which is the actual component that turns xml/annotations into classes and manages the lifecycle of each.
A ContextLoaderListener is used when spring is running inside another container (eg a servlet engine like tomcat) to detect the startup of the application and initialise the ApplicationContext. When the spring is used in another context -eg a java program run through a main method - the application can create the AppContext directly without needing the ContextLoaderListener like this:
public class Main {
public static void main(String[] args) throws Exception {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"context.xml");
Foo foo = (Foo) ctx.getBean("fooBean");
foo.doSomethingCool();
}
}
DispatcherServlet and ContextLoaderListener in Spring
The root WebApplicationContext is a Spring Application Context shared across the application.
A DispatcherServlet instance actually has its own
WebApplicationContext.
One can have multiple DispatcherServlet instances in an application, and each will have its own WebApplicationContext.
The root WebApplicationContext is shared across
the application, so if you have a root WebApplicationContext and
multiple DispatcherServlets, the DispatcherServlets will share the
root WebApplicationContext.
However, for a simple Spring MVC application, one can even have a situation where there is no need to have a root WebApplicationContext. A DispatcherServlet would still have its own WebApplicationContext, but it doesn’t actually need to have a parent root WebApplicationContext.
So, which beans should go in the root Web Application Context and which beans should go in the DispatcherServlet’s Web Application Context?
Well, general beans such as services and DAOs make their way in root Web Application Context, and more web-specific beans such as controllers are included in DispatcherServlet’s Web Application Context.
ContextLoaderListener or not?
In your case, no, there's no reason to keep the ContextLoaderListener
and applicationContext.xml
. If your app works fine with just the servlet's context, that stick with that, it's simpler.
Yes, the generally-encouraged pattern is to keep non-web stuff in the webapp-level context, but it's nothing more than a weak convention.
The only compelling reasons to use the webapp-level context are:
- If you have multiple
DispatcherServlet
that need to share services - If you have legacy/non-Spring servlets that need access to Spring-wired services
- If you have servlet filters that hook into the webapp-level context (e.g. Spring Security's
DelegatingFilterProxy
,OpenEntityManagerInViewFilter
, etc)
None of these apply to you, so the extra complexity is unwarranted.
Just be careful when adding background tasks to the servlet's context, like scheduled tasks, JMS connections, etc. If you forget to add <load-on-startup>
to your web.xml
, then these tasks won't be started until the first access of the servlet.
Adding ContextLoaderListener to web.xml in Spring MVC
Yes you need to add ContextLoaderListener
in web.xml
,
only if you want to load other Spring context xml files as well while loading the app
and you can specify them as
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-security.xml
</param-value>
</context-param>
Confused about using ContextLoaderListener in Spring MVC
the xml files specified above are located on the root of the classpath. i.e. WEB-INF/classes
. See here for more details
Adding ContextLoaderListener to web.xml in Spring MVC
Yes you need to add ContextLoaderListener
in web.xml
,
only if you want to load other Spring context xml files as well while loading the app
and you can specify them as
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-security.xml
</param-value>
</context-param>
Related Topics
Jni Converting Jstring to Char *
Generating All Possible Permutations of a List Recursively
Native Query with Named Parameter Fails with "Not All Named Parameters Have Been Set"
How to "Pretty Print" a Duration in Java
Difference Between Class and Type
How to Use the Command Update-Alternatives --Config Java
Check If Int Is Between Two Numbers
How to Get Which Jradiobutton Is Selected from a Buttongroup
Why I'm Not Able to Unwrap and Serialize a Java Map Using the Jackson Java Library
Why Should I Care That Java Doesn't Have Reified Generics
Jtable + Sorting Specific Field
Foreach VS Foreachordered in Java 8 Stream
What Are the Differences Between Char Literals '\N' and '\R' in Java
Multiple Runwith Statements in Junit