spring 3 mvc多个应用程序上下文实例

时间:2010-09-09 18:54:38

标签: spring web-config

这是我的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>

为什么创建了两个应用程序上下文实例? 当我使用@Scheduled添加一个调度方法时,由于这两个应用程序上下文,它会被调用两次。

3 个答案:

答案 0 :(得分:3)

您正在加载相同spring配置文件的两倍。当然,您有两个独立的应用程序上下文。首先,我将DispatcherServerlet的servlet名称重命名为“spring3mvc”。 servlet定义应如下所示:

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

如果你有这种方式,你的“WEB-INF”目录中应该有一个spring配置文件“spring3Mvc-servlet.xml”。由于正确的命名约定,Spring将自动找到此文件。在这个文件中,您应该拥有对springMVC很重要的bean。它看起来像这样:

<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>

这应该可以解决您的问题。

答案 1 :(得分:3)

我注意到你有

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

在以下块中

<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>

尝试删除...它对我有用

答案 2 :(得分:1)

您的web.xml中是否有其他弹簧过滤器或jsp页面未显示在您的代码段中?

我问,回答你的问题,因为我相信Spring documentation的引用可以解释可能发生的事情......

  

“在网络MVC框架中,每个   DispatcherServlet有自己的   WebApplicationContext,继承   所有已经在中定义的bean   root WebApplicationContext。这些   继承bean定义的可以   在特定于servlet中重写   范围和新范围特定的bean   可以在给定的本地定义   servlet实例。“

如果对我的web.xml问题回答“是”,那么我的猜测是Spring在创建spring过滤器时(通过ContextLoaderListener)实例化根WebApplicationContext。所以,这会发生在......之前......

然后,当创建DispatcherServlet时,“contextConfigLocation”引用相同的文件(即相同的bean名称),因此新的WebApplicationContext将获取该servlet本地的重写bean名称!

我想知道,即使你回答“不”,无论如何这仍然可能发生。由于您设置了“contextConfigLocation”(由ContextLoaderListener使用)并在DispatcherServlet配置中“覆盖”它;我假设Spring没有检查这些配置是否使用相同的文件集。

您可以通过调试器运行这些方案,并在WebApplicationContext方法上放置断点以确定。

解决方法:

要解决问题,请:

1)确保您的2个contextConfigLocations在他们使用的文件中不重叠

或者:

2)在自己的xml文件中分解Scheduling bean,并确保它只被2个contextConfigLocations中的一个引用