Spring 3 MVC несколько экземпляров контекста приложения - PullRequest
2 голосов
/ 09 сентября 2010

вот мой 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 ]

3 голосов
/ 13 апреля 2011

Я заметил, что у вас есть

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

попробуй удалить это ... у меня сработало

3 голосов
/ 15 марта 2011

Вы дважды загружаете одни и те же весенние конфигурационные файлы.Конечно, у вас есть два отдельных контекста приложения.Сначала я бы переименовал имя сервлета для DispatcherServerlet в «spring3mvc».Определение сервлета должно выглядеть следующим образом:

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

Если вы используете его таким образом, у вас должен быть конфигурационный файл spring "spring3Mvc-servlet.xml" в вашем каталоге "WEB-INF".Spring найдет этот файл автоматически из-за правильного соглашения об именах.В этом файле у вас должны быть только бины, которые важны для springMVC.Это может выглядеть так:

<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 голос
/ 07 мая 2011

Есть ли у вас другие весенние фильтры или jsp-страницы в вашем web.xml, не показанные в вашем фрагменте кода?

Я прошу ответить на ваш вопрос, потому что я верю, что эта цитата из Весенняя документация может объяснить, что может происходить ...

"В веб-фреймворке MVC каждый ДиспетчерСервлет имеет свой WebApplicationContext, который наследует все бобы уже определены в root WebApplicationContext. Эти унаследованные бобы могут быть определены переопределено в сервлете область действия и новые специфические для области компоненты может быть определен локально для данного экземпляр сервлета. "

Если вы ответили «да» на мой вопрос web.xml, то я предполагаю, что Spring создает корневой WebApplicationContext при создании весеннего фильтра (через ContextLoaderListener). Так что это произойдет ДО ...

Затем, когда создается DispatcherServlet, «contextConfigLocation» ссылается на те же файлы (то есть, на те же имена компонентов), поэтому новый WebApplicationContext получает переопределенные имена компонентов, локальные для этого сервлета!

Интересно, даже если вы ответите "нет", может ли это все равно произойти. Так как вы устанавливаете «contextConfigLocation» (используется ContextLoaderListener) и «переопределяете» его в конфигурации DispatcherServlet; Я предполагаю, что Spring не проверяет, используют ли эти конфигурации один и тот же набор файлов.

Вы можете запустить эти сценарии через отладчик и установить точки останова в методах WebApplicationContext, чтобы точно это выяснить.

Обход:

Чтобы решить проблему, либо:

1) убедитесь, что ваши 2 contextConfigLocations не перекрываются в используемых ими файлах

Или:

2) выделить компонент планирования в его собственном XML-файле и убедиться, что на него ссылается только один из 2 contextConfigLocations

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...