-1

I have a web app that uses Spring MVC. Many of the Spring components spin of threads and do a lot of asynchronous processing. I was noticing that the web app seemed to be running a lot more asynchronous processes than it should be, so I looked into it, and I realized that for some reason my web app had launched 2 Spring contexts -- using the same Spring XML configuration file -- meaning 2 copies of every Spring bean, and twice as many asynchronous threads and background processes as there should have been. I've seen a number of other stackoverflow questions about Spring MVC and multiple Spring contexts, which have helped explain why Spring allows this behavior, but none of these answers have explained how to fix this to only use 1 Spring context. See this question where the response says "Yes you can have one context only" but doesn't explain how to achieve that: https://stackoverflow.com/a/18698392/367544

Here's my web.xml file:

<context-param>
    <param-name>contextConfigLocation</param-name>
     <param-value>/WEB-INF/spring-configuration/application-config.xml</param-value>
</context-param>

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

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>


<filter>
    <filter-name>AuthFilter</filter-name>
    <filter-class>...</filter-class>
</filter>
<filter-mapping>
    <filter-name>AuthFilter</filter-name>
    <url-pattern>/app/*</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>SpringDispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-configuration/application-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>SpringDispatcherServlet</servlet-name>
    <url-pattern>/app/*</url-pattern>
</servlet-mapping>

As you can see, the application-config.xml Spring XML configuration file is referenced multiple times (once in the "context-param" and once in the "servlet"), so I tried removing this part from the beginning:

<context-param>
    <param-name>contextConfigLocation</param-name>
     <param-value>/WEB-INF/spring-configuration/application-config.xml</param-value>
</context-param>

But that made my web app fail to startup. How can I fix my web.xml file to only use one global Spring context for everything so I don't have multiple copies of everything running?

Dasmowenator
  • 5,505
  • 5
  • 36
  • 50

2 Answers2

0

I was able to solve it by removing not just the "context-param" part, but also the "listener" part:

<context-param>
    <param-name>contextConfigLocation</param-name>
     <param-value>/WEB-INF/spring-configuration/application-config.xml</param-value>
</context-param>

<listener>
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Dasmowenator
  • 5,505
  • 5
  • 36
  • 50
0

Use 2 different .xml files, one defines spring context,load by ContextLoaderListener. The other one defines MVC context, load by DispatcherServlet.

In MVC context, define all beans ONLY been used as "dispatcher", i.e. Controllers, which is not used by other beans.

In Spring context, define all other beans, basically Services and DAOs.

If you are using component-scan, you can use context:exclude-filter and context:include-filter

In Spring context:

<context:component-scan base-package="scan.package">
    <context:exclude-filter
            type="annotation"
            expression="org.springframework.stereotype.Controller"/>
    <context:exclude-filter
            type="annotation"
            expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>

In MVC context:

   <context:component-scan base-package="scan.package">
        <context:include-filter
                type="annotation"
                expression="org.springframework.stereotype.Controller"/>
        <context:include-filter
                type="annotation"
                expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
    </context:component-scan>
John
  • 1,654
  • 1
  • 14
  • 21