Почему DispatcherServlet создает другой контекст приложения? - PullRequest
25 голосов
/ 20 октября 2011

Я сконфигурировал контекст корневого приложения, используя ContextLoaderListener и контекстный параметр init contextConfigLocation.

Затем к корневому контексту обращается переменная-преобразователь JSF (* .jsf).Это работает нормально.

Теперь проблема в том, что запросы (* .do), проходящие через DispatcherServlet, получат другой контекст приложения, и затем синглтон-бины будут созданы дважды.

Я не знаюДля DispatcherServlet нужен другой контекст приложения, как я могу указать его для повторного использования существующего корневого контекста приложения, который загружается ContextLoaderListener?

NOTE

После прочтения справочных страниц в ответах я знаю, что между корневым контекстом и контекстом диспетчера существует разделение контекста, но ни одна из ссылок не говорит мне, куда идти.Итак, вот мое решение, может быть полезным для других людей, сталкивающихся с подобным вопросом:

  1. В XML-файле конфигурации контекста для сервлета диспетчера: dispatcher-servlet.xml, я продублировал определение <context:component-scan/>, котороеуже определен в корневом контексте.Так что убери это.dispatcher-servlet.xml должен определять только те компоненты, которые используются только для Spring MVC.

  2. Все контроллеры уже отсканированы и созданы в корневом контексте, однако Spring MVC по умолчанию не 'зарегистрировать контроллеры в корневом контексте для сопоставления запросов.Вы можете либо:

    2.1.В корневом контексте исключите @Controller из <component-scan> и сканируйте @Controller только в файле dispatcher-servlet.xml.

    2.2.Или установите для свойства DefaultAnnotationHandlerMapping.detectHandlersInAncestorContexts значение true:

    (dispatcher-servlet.xml:)
    
    <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="detectHandlersInAncestorContexts" value="true" />
    </bean>
    

Ответы [ 2 ]

25 голосов
/ 20 октября 2011

Чтобы ответить на ваш первый вопрос, DispatcherServlet создает контекст, потому что именно так он позволяет себя настраивать, и если у вас есть несколько DispatcherServlet в одном приложении, каждый из них должен быть настроен отдельно.Поэтому каждый получает свой собственный контекст, и каждый из этих контекстов отделен от «корневого» контекста, где должны жить все ваши настоящие «рабочие» бины, чтобы они могли быть разделены между другими контекстами.За последние пару недель было несколько вопросов, которые возникли из-за путаницы по этой самой проблеме.Вы можете лучше понять, как все работает, проверив ответы:

Справка / объяснение иерархии конфигурации XML-файлов Spring

Объявление Spring Bean в ParentКонтекст против дочернего контекста

Spring-MVC: что такое "контекст" и "пространство имен"?

4 голосов
/ 20 октября 2011

Если у вас работает DispatcherServlet, нет необходимости использовать ContextLoaderListener. Просто используйте ContextLoader.getCurrentWebApplicationContext() для доступа к WebApplicationContext.

Просто держите определения компонентов отдельно , как указано в предыдущем ответе .

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