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

О нескольких контейнерах в структуре spring

В типичном проекте Spring MVC есть два "контейнера": один, созданный ContextLoaderListener, а другой созданный DispatchServlet.

Я хочу знать, действительно ли это два экземпляра контейнера IoC? (Я вижу два файла конфигурации bean, один - root-context.xml, другой - servlet-context.xml)

Если есть 2 контейнера, то какие отношения?

Можно ли использовать beans в одном контейнере в другом контейнере?

4b9b3361

Ответ 1

Из Spring Официальный сайт:

Интерфейс org.springframework.context.ApplicationContextпредставляет контейнер Spring IoC и отвечает за создание, настройка и сборка вышеупомянутого beans. Контейнер получает свои инструкции о том, какие объекты нужно создавать, настраивать и собирать, считывая метаданные конфигурации. метаданные конфигурации представлены в XML, аннотациях Java или Java-код.

Снова из официального Дока:

В среде Web MVC каждый DispatcherServlet имеет свой собственный WebApplicationContext, который наследует все beans, уже определенные в корневой WebApplicationContext. Эти унаследованные beans могут быть переопределяется в области, зависящей от сервлета, и вы можете определить новые специфичный для области beans локальный для данного экземпляра сервлета.

Теперь приступим к вашему Вопросу, как указано здесь:

В Spring веб-приложениях есть два типа контейнера, каждый из которых который настроен и инициализирован по-разному. Один из них "Контекст приложения", а другой - "Контекст веб-приложений". Позволяет сначала поговорить о "Контексте приложений". Контекст приложения это контейнер, инициализированный ContextLoaderListener или ContextLoaderServlet, определенный в файле web.xml и конфигурации будет выглядеть примерно так:

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

<context-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>classpath:*-context.xml</param-value>
</context-param>

В приведенной выше конфигурации я прошу Spring загрузить все файлы из classpath, которые соответствуют * -context.xml и создают приложение Контекст из него. Этот контекст может, например, содержать компоненты таких как транзакционные службы промежуточного уровня, объекты доступа к данным или другие объекты, которые вы, возможно, захотите использовать (и повторно использовать) через выражение. Для каждого приложения будет один контекст приложения.

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

<servlet>
      <servlet-name>platform-services</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:platform-services-servlet.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
</servlet>

Вы указываете имя конфигурационного файла Spring в качестве сервлета параметр инициализации. Важно помнить, что имя XML должно иметь вид -servlet. XML. В этом примере имя сервлета - это платформы-службы поэтому имя нашего XML должно быть platform-service-servlet.xml. Какие бы beans не были доступны в ApplicationContext из каждого WebApplicationContext. Рекомендуется использовать четкое разделение между службами среднего уровня, такими как бизнес-логика компонентов и классов доступа к данным (которые обычно определяются в ApplicationContext) и веб-компонентов, таких как контроллеры и просматривать разрешители (которые определены в WebApplicationContext per Диспетчерский сервлет).

Проверьте эти ссылки

Разница между applicationContext.xml и spring -servlet.xml в Spring Framework

http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-basics

Ответ 2

Создано не два отдельных контейнера. Как правило, вы хотите, чтобы spring создавал объект, объявленный в файле servlet-context.xml, когда объект требуется. Таким образом, вы сопоставляете файл конфигурации servlet-context.xml с Servlet диспетчера, то есть хотите инициализировать объект, когда запрос попадает в сервлет диспетчера.

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

Если as, если вы хотите инициализировать объект и выполнить действие при загрузке контекста, вы объявите файл конфигурации в тегах context-param дескриптора развертывания.

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

Вы можете протестировать это, написав, объявив отдельный beans в servlet-context.xml и root-context.xml, а затем, автоподвешивая их в пользовательском классе List Lister для контекстного загрузчика. Вы найдете только инициализированные экземпляры корневого контекста, а servlet-context beans - null.

Ответ 3

Spring MVC имеет как минимум 2 контейнера -

  • Контекст приложения, объявленный

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml</param-value>
    </context-param>
    
  • Контекст сервлета, объявленный -

    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    

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