Подтвердить что ты не робот

Порядок загрузки contextConfigLocation в web.xml проекта Spring Servlet

Предположим, что у меня есть проект Spring Java, и я пытаюсь настроить его как сервлет веб-сервера. Вот усеченная версия файла web.xml:

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

<servlet>
    <servlet-name>my-servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/specificApplicationContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>my-servlet</servlet-name>
    <url-pattern>/foo/*</url-pattern>
</servlet-mapping>

Ключевым моментом здесь является то, что я указал два загружаемых файла XML. Один из них является общим для моего приложения, а другой - для сервлета "my-servlet". Для настройки с одним сервлет-отображением это не имеет смысла. Тем не менее, мой проект имеет несколько отображений сервлета, и каждый из них имеет специальные настройки Spring.

Мой вопрос: Какой контекстConfigLocation будет загружен сначала Spring? Будет ли это generalApplicationContext.xml или это будет specificApplicationContext.xml? Что еще более важно, действительно ли порядок загрузки даже материи? Из моих усилий по отладке кажется очевидным, что это происходит, потому что я получаю разные ошибки, когда я перемещаю некоторую независимую конфигурацию Spring из одного файла в другой.

Примечание. Хорошая практика дискуссионная или нет, если использовать несколько конфигураций Spring для нескольких сопоставлений сервлетов. То же самое касается использования конфигурации XML вместо новой конфигурации Java. Но это не то, что я пытаюсь спросить здесь. Попробуем сосредоточиться на моем главном вопросе.

4b9b3361

Ответ 1

generalApplicationContext.xml - это тот, который будет загружен первым, потому что это ApplicationContext, загруженный с ContextLoaderListener

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

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

specificApplicationContext.xml на самом деле представляет собой дочерний контекст выше загруженного generalApplicationContext.xml, и он будет WebApplicationContext

<servlet>
    <servlet-name>my-servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/specificApplicationContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>my-servlet</servlet-name>
    <url-pattern>/foo/*</url-pattern>
</servlet-mapping>

И да, порядок загрузки имеет значение. Поскольку при загрузке родительского контекста необходимо выполнить все необходимые зависимости.

Ответ 2

Следующая часть загружает файл контекста и создает ApplicationContext. Этот контекст может содержать, например, такие компоненты, как транзакционные службы промежуточного уровня, объекты доступа к данным или другие объекты, которые вы, возможно, захотите использовать (и повторно использовать) в приложении. Для каждого приложения будет один контекст приложения.

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

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

<servlet>
    <servlet-name>my-servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/specificApplicationContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

Подробнее см. и this

Ответ 3

Какой лучший способ на самом деле иметь журналы отладки Spring, скажут вам сам заказ. Если вы хотите войти в код, вы также можете взглянуть на org.springframework.web.servlet.FrameworkServlet (DispatcherServlet расширяет этот класс) Просто включите logger "org.springframework.web.servlet" для отладки уровня в предпочитаемой структуре ведения журнала

Вот как обычно выглядят журналы: очевидно, что корневой контекст загружается первым и устанавливается как родительский для иерархической контекста - контекст сервлета загружается далее.

INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/generalApplicatonContext.xml]
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 256 ms
DEBUG: org.springframework.web.servlet.DispatcherServlet - Initializing servlet 'my-servlet'
INFO :Initializing Spring FrameworkServlet 'appServlet'
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'my-servlet': initialization started
DEBUG: org.springframework.web.servlet.DispatcherServlet - Servlet with name 'appServlet' will try to create custom WebApplicationContext context of class 'org.springframework.web.context.support.XmlWebApplicationContext', using parent context [Root WebApplicationContext: startup date [Fri May 15 17:08:24 IST 2015]; root of context hierarchy
DEBUG: Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/specificApplicationContext.xml

Ответ 4

Если у вас есть ContextLoaderListener, в вашем web.xml spring сначала загрузится generalApplicationContext.xml. Это создаст beans и предоставит им все сервлеты и фильтры. Этот xml должен иметь общие классы beans, которые используются в вашем приложении.

Позже контейнер spring загрузит specificApplicationContext.xml, потому что у вас есть загрузка при запуске в конфигурации сервлета. Если вы не укажете загрузку при запуске, этот specificApplicationContext.xml будет загружаться, когда первый запрос появится в вашем приложении с определенным шаблоном url.

В качестве вашего вопроса, когда вы перемещаете команду springconfig из одной конфигурации в другую, это изменит доступность ресурсов приложения к контейнеру. Если вы укажете Controller beans в generalApplicationContext.xml и не укажете их в specificApplicationContext.xml, то ваш DispatcherServlet не найдет сопоставления, поэтому вы увидите ошибку 404.

Если вы хотите создать несколько объектов bean по запросу, вы можете создать еще один сервлет-конфиг для загрузки этого специфического конкретного файлаConfigurationFile2.xml и сопоставить его с шаблоном url.