ContextLoaderListener или нет? - PullRequest
       15

ContextLoaderListener или нет?

122 голосов
/ 26 января 2012

Стандартное весеннее веб-приложение (созданное с помощью шаблона Roo или Spring MVC Project) создает файл web.xml с ContextLoaderListener и DispatcherServlet. Почему они не только используют DispatcherServlet и загружают его полностью?

Я понимаю, что ContextLoaderListener должен использоваться для загрузки материала, не относящегося к сети, а DispatcherServlet используется для загрузки материала, относящегося к сети (Controllers, ...). И это приводит к двум контекстам: родительский и дочерний контекст.

Справочная информация:

Я делал это стандартным способом в течение нескольких лет.

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Handles Spring requests -->
<servlet>
    <servlet-name>roo</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/spring/webmvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

Это часто вызывало проблемы с двумя контекстами и зависимостями между ними. В прошлом мне всегда удавалось найти решение, и у меня было сильное чувство, что это всегда делает структуру / архитектуру программного обеспечения лучше. Но теперь я сталкиваюсь с проблемой с событиями в обоих контекстах .

- Однако это заставляет меня переосмыслить эту модель двух контекстов, и я спрашиваю себя: почему я должен попасть в эту проблему, почему бы не загрузить все файлы конфигурации Spring одним DispatcherServlet и полностью удалить ContextLoaderListener. (У меня все еще будут разные конфигурационные файлы, но только один контекст.)

Есть ли причина не удалять ContextLoaderListener?

Ответы [ 3 ]

86 голосов
/ 26 января 2012

В вашем случае нет, нет никаких причин оставлять ContextLoaderListener и applicationContext.xml. Если ваше приложение работает нормально только с контекстом сервлета, то придерживайтесь этого, это проще.

Да, общепринятая схема заключается в том, чтобы хранить не-веб-контент в контексте уровня веб-приложения, но это не более чем слабое соглашение.

Единственными вескими причинами для использования контекста уровня веб-приложения являются:

  • Если у вас есть несколько DispatcherServlet, которым нужно совместно использовать службы
  • Если у вас есть устаревшие / не Spring сервлеты, которым нужен доступ к сервисам Spring-wired
  • Если у вас есть фильтры сервлетов, которые подключаются к контексту уровня веб-приложения (например, DelegatingFilterProxy, OpenEntityManagerInViewFilter и т. Д.) Spring Security

Ничто из этого не относится к вам, поэтому дополнительная сложность неоправданна.

Просто будьте осторожны при добавлении фоновых задач в контекст сервлета, таких как запланированные задачи, соединения JMS и т. Д. Если вы забудете добавить <load-on-startup> в web.xml, то эти задачи не будут запущены до первого доступа сервлета.

10 голосов
/ 28 ноября 2013

Вы можете настроить контекст приложения и наоборот. Например. чтобы заставить OpenEntityManagerInViewFilter работать. Установите ContextLoaderListener , а затем настройте ваш DispatcherServlet с помощью:

<servlet>
    <servlet-name>spring-mvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value></param-value>
    </init-param>
</servlet>

Просто убедитесь, что значение параметра contextConfigLocation пусто.

10 голосов
/ 25 декабря 2012

Я хочу поделиться тем, что я сделал в своем приложении Spring-MVC:

  1. В we-mvc-config.xml я добавил только классы, аннотированные @Controller:

    <context:component-scan base-package="com.shunra.vcat">
        <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    </context:component-scan>
    
  2. К файлам applicationContext.xml я добавил все остальные:

    <context:component-scan base-package="com.shunra.vcat">
        <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    </context:component-scan>
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...