Spring-mvc – Web-application context/ root application context and transaction manager setup

spring-mvc

I had two questions,

In Spring MVC application, what is the purpose of having ContextLoaderListener?

Below are the my entries in web.xml,
All MVC beans are defined in servlet-context.xml
All database and annotation based transaction management is defined in applicationContext.xml and I'm using container managed transaction in JBoss

The trasaction manager works fine if I pass the applicationContext.xml as highlighted below as to DispatcherServlet. But I thought we should only pass the Spring MVC context info to DispatcherServlet.

If I remove the applicationContext.xml the transaction manager stops working? I'm confused what is best way of managing the context files?

Web.xml

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>    
        /WEB-INF/config/applicationContext.xml
        /WEB-INF/config/spring-mail.xml
    </param-value>
</context-param>
<context-param>
    <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
    <param-value>messages</param-value>
</context-param>


<servlet>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/config/servlet-context.xml
           ***/WEB-INF/config/applicationContext.xml***
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:jee="http://www.springframework.org/schema/jee"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xmlns:aop="http://www.springframework.org/schema/aop"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<!-- registers all of Spring's standard post-processors for annotation-based configuration -->
<context:annotation-config />

<jee:jndi-lookup id="dataSource" jndi-name="java:OracleDS"/>


<tx:annotation-driven/>
<tx:jta-transaction-manager/>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="configLocation"
              value="classpath:com/common/model/config/sqlmapconfig.xml"/>
</bean>

<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg ref="sqlSessionFactory"/>
</bean>

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:mvc="http://www.springframework.org/schema/mvc"
   xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<!-- Scans the classpath of this application for @Components to deploy as beans -->
<context:component-scan base-package="com.xxxx"/>

<!-- Configures the @Controller programming model -->
<mvc:annotation-driven/>

<!-- Configures Handler Interceptors -->
<mvc:interceptors>
    <!-- Changes the locale when a 'locale' request parameter is sent; e.g. /?locale=de -->
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
    <!--Register Request/Response Interceptor-->
    <bean class="com.xxx.common.auditor.RequestInterceptor"/>
   <!-- <bean class="com.xxx.common.interceptor.UserAuthenticationInterceptor"/>-->
</mvc:interceptors>

<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/>

<!-- Application Message Bundle -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename" value="/WEB-INF/messages/messages"/>
    <property name="cacheSeconds" value="0"/>
</bean>


<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/views/"/>
    <property name="suffix" value=".jsp"/>
</bean>

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location">
        <value>/WEB-INF/xxxx.properties</value>
    </property>
</bean>

Thanks for you help! I know its quote long, but wanted to make myself understood better

Best Answer

As explained in the documentation, every dispatcher servlet has its own application context, where you typically define controllers, view resolvers, etc., and which inherits (and can override beans) from a root application context, which typically contains data source definitions, middle tier services, etc.

The ContextLoaderListener, as its documentation explains, is used to to start up and shut down Spring's root application context (from which the servlet contexts inherit).

It's also useful when you want to use Spring for your middle tier, but you don't want to use Spring MVC as your presentation layer. In this case, you only define a root application context using ContextLoaderListener.

Related Topic