Контекст Spring загружается дважды, когда Spring DispatcherServlet используется из MeteorServlet Atmosphere

#java #spring #spring-mvc #spring-security

#java #spring #spring-mvc #spring-безопасность

Вопрос:

Я пытаюсь настроить веб-приложение, которое использует

  1. Spring 3.2.x
  2. Spring Security 3.x
  3. Атмосфера 2.x

Я начал использовать этот пример SpringMVC-Atmosphere-Example .

Используя это web.xml конфигурация:

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

<web-app version="3.0" id="WebApp_ID" metadata-complete="true" 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_3_0.xsd">

<display-name>Example Project</display-name>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <async-supported>true</async-supported>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>gui-dispatcher</servlet-name>
    <servlet-class>org.atmosphere.cpr.MeteorServlet</servlet-class>
    <async-supported>true</async-supported>

    <init-param>
        <param-name>org.atmosphere.servlet</param-name>
        <param-value>org.springframework.web.servlet.DispatcherServlet</param-value>
    </init-param>

    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-context.xml</param-value>
    </init-param>

    <init-param>
        <param-name>org.atmosphere.cpr.broadcasterClass</param-name>
        <param-value>org.atmosphere.cpr.DefaultBroadcaster</param-value>
    </init-param>

    <init-param>
        <param-name>org.atmosphere.cpr.broadcaster.shareableThreadPool</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>org.atmosphere.useNative</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>org.atmosphere.useWebSocket</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>org.atmosphere.useStream</param-name>
        <param-value>true</param-value>
    </init-param>

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

<servlet-mapping>
    <servlet-name>gui-dispatcher</servlet-name>
    <url-pattern>/main/*</url-pattern>
</servlet-mapping>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/security/spring-security.xml
        /WEB-INF/spring-context.xml
    </param-value>
</context-param>


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

<listener>
    <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
</web-app>
 

Я получаю контекст приложения Spring для сервлета Spring Dispatcher, который будет загружен дважды. Почему он загружается дважды и как я могу предотвратить эту дублирующуюся загрузку контекста?

Комментарии:

1. Я думаю, что метеорит, о котором вы здесь упомянули, — это другой тип метеора или атмосферы?

2. @Akshat Это, по-видимому, связано с этим: github.com/Atmosphere/atmosphere не атмосфера .

Ответ №1:

Это потому, что у вас есть как a org.springframework.web.context.ContextLoaderListener , так и a org.springframework.web.servlet.DispatcherServlet , определенные в вашем web.xml , обрабатывая то же самое spring-context.xml

org.springframework.web.context.ContextLoaderListener будет вызван при первом развертывании вашего веб-приложения и создаст один Spring ApplicationContext с использованием /WEB- INF/spring-context.xml and /WEB-INF/security/spring-security.xml .

Затем будут созданы сервлеты для вашего веб-приложения, один из которых, по-видимому, делегируется сервлету Spring Dispatcher. Это создаст ApplicationContext только новое using /WEB-INF/spring-context.xml .

Вот почему вы видите, что ваш ApplicationContext создается дважды. Чтобы предотвратить это, используйте либо the DispatcherServlet , либо the ContextLoaderListener для создания вашего ApplicationContext . Учитывая вашу потребность в интеграции с другим фреймворком, я подозреваю, что самым простым вариантом может быть использование DispatcherServlet .

Ответ №2:

Используйте фильтры по умолчанию для applicationContext.xml и mvc-dispatcher-servlet.xml .

  1. applicationContext.xml
    <контекст:component-scan base-package=»com.companyname»>
    <контекст:exclude-filter type=»аннотация» выражение=»org.springframework.stereotype.Контроллер»/> </context:component-scan>
  2. mvc-dispatcher-servlet.xml
    <контекст:component-scan base-package=»com.companyname» использовать-default-filters=»false»>
    <контекст: включить-тип фильтра=»аннотация» выражение=»org.springframework.stereotype.Контроллер»/> </context:component-scan>
  3. Удалить applicationContext.xml и mvc-dispatcher-servlet.xml ссылка из web.xml
  4. В ApplicationContext импортируйте Security-context.xml