开发者

spring 3 mvc multiple application context instances

here is my web.xml:

<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<!-- Enables clean URLs with JSP views e.g. /welcome instead of /app/welcome -->
<filter>
    <filter-name>UrlRewriteFilter</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/*.xml
        </param-value>
</context-param>
<!-- Handles all requests into the application -->
<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/spring/*.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<!-- Maps all /app requests to the DispatcherServlet for handling -->
<servlet-mapping>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Why there are two instances of application context created? When I add a scheduled method with @Scheduled it is invoked twice, because of those two application contexts.


You are loading twice times the same spring config files. Of course you have two separate application contexts. At first I would rename the servlet name for the DispatcherServerlet to "spring3mvc". The servlet definition should look like this:

<servlet>
        <servlet-name>spring3Mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

If you have it in this way, you should have a spring config file "spring3Mvc-servlet.xml" in your "WEB-INF" directory. Spring will find this file automatically because of the right naming convention. In this file you should just have the beans who are important for springMVC. It could look like this:

<context:component-scan base-package="org.company.gui.controller"/>

<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".view.jsp"/>
</bean>

This should fix your problem.


I noticed that you have

<load-on-startup>1</load-on-startup>  

in the following block

<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/spring/*.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

try removing that... it worked for me


Do you have any other spring filters or jsp pages in your web.xml not shown in your code snippet?

I ask, to answer your question, because I believe this quote from Spring documentation could explain what might be happening...

"In the web MVC framework, each DispatcherServlet has its own WebApplicationContext, which inherits all the beans already defined in the root WebApplicationContext. These inherited beans defined can be overridden in the servlet-specific scope, and new scope-specific beans can be defined local to a given servlet instance."

If you answered "yes" to my web.xml question, then my guess is that Spring instantiates a root WebApplicationContext when a spring filter is created (via ContextLoaderListener). So, this would happen BEFORE...

Then, when the DispatcherServlet is created, the "contextConfigLocation" refers to the same files (that is, the same bean names), so a new WebApplicationContext gets overridden bean names local to that servlet!

I wonder, even if you answered "no", whether this might still happen anyway. Since you set "contextConfigLocation" (used by the ContextLoaderListener) and "override" it in DispatcherServlet configuration; I assume Spring is not checking whether those configurations are using the same file set.

You can run these scenarios through a debugger and put breakpoints on WebApplicationContext methods to find out for sure.

Workaround:

To solve the problem, either:

1) make sure your 2 contextConfigLocations don't overlap in files they use

Or:

2) break out the Scheduling bean in its own xml file and make sure it's referred to by only one of the 2 contextConfigLocations

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜