В чем разница между ApplicationContext и WebApplicationContext в Spring MVC?

193

В чем разница между контекстом приложения и контекстом веб-приложения?

Я в курсе, что WebApplicationContextиспользуется для приложений, ориентированных на архитектуру Spring MVC?

Я хочу знать, какая польза от ApplicationContextприложений MVC? И какие бобы определены в ApplicationContext?

Сумит Трехан
источник
5
Я не верю, что это дубликат stackoverflow.com/questions/3652090/… Этот вопрос задает вопрос о содержимом web.xmlфайла; этот вопрос задает о некоторых классах Spring.
Raedwald
@Raedwald, это не правда. Другой вопрос, о котором речь не идет, web.xmlно он говорит о вариантах конфигурации bean-компонентов Spring XML ApplicationContextи WebApplicationContext. Все определения bean в applicationContext.xmlбудут доступны в то ApplicationContextвремя как все определения bean в *-servlet.xmlбудут доступны в a WebApplicationContext.
g00glen00b

Ответы:

229

Контекст веб-приложения расширенный контекст приложения, который предназначен для работы со стандартным javax.servlet.ServletContext, чтобы он мог взаимодействовать с контейнером.

public interface WebApplicationContext extends ApplicationContext {
    ServletContext getServletContext();
}

Бины, созданные в WebApplicationContext, также смогут использовать ServletContext, если они реализуют интерфейс ServletContextAware.

package org.springframework.web.context;
public interface ServletContextAware extends Aware { 
     void setServletContext(ServletContext servletContext);
}

С экземпляром ServletContext можно сделать много вещей, например, получить доступ к ресурсам WEB-INF (конфигам xml и т. Д.), Вызвав метод getResourceAsStream (). Обычно все контексты приложения, определенные в web.xml в приложении Spring сервлета, являются контекстами веб-приложения, это относится как к контексту корневого веб-приложения, так и к контексту приложения сервлета.

Кроме того, в зависимости от возможностей контекста веб-приложения тестирование вашего приложения может быть немного сложнее, и вам может понадобиться использовать класс MockServletContext для тестирования.

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

Это позволяет вам запускать некоторые сервисы как синглтоны для всего приложения (здесь обычно находятся bean-компоненты Spring Security и базовые сервисы доступа к базам данных), а другие как отдельные сервисы в соответствующих сервлетах, чтобы избежать конфликта имен между bean-компонентами. Например, один контекст сервлета будет обслуживать веб-страницы, а другой будет реализовывать веб-службу без сохранения состояния.

Это двухуровневое разделение возникает сразу после использования классов сервлетов Spring: для настройки контекста корневого приложения вы должны использовать тег context-param в вашем файле web.xml.

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

(контекст корневого приложения создается ContextLoaderListener, который объявлен в web.xml

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

) И сервлет тег для контекста приложения сервлета

<servlet>
   <servlet-name>myservlet</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>app-servlet.xml</param-value>
   </init-param>
</servlet>

Обратите внимание, что если init-param будет опущен, то Spring будет использовать myservlet-servlet.xml в этом примере.

Смотрите также: Разница между applicationContext.xml и spring-servlet.xml в Spring Framework

Борис Треухов
источник
2
Большое спасибо за ответ. Я слышал, что есть два типа контекстов, также используемых для веб-приложения. Один служит в качестве контекста корневого приложения, где определения, не связанные с сетью, предоставляются в качестве примера службы, конфигурации dao и т. Д., А другой - для конкретной веб-конфигурации, такой как сопоставления обработчиков и т. Д. Предыдущий служит родительским контекстом, а последний - дочерним контекстом. , Я хочу знать, как объявить эту структуру. Я слышал о некоторых обратных вызовах ContextListener. Но я не совсем уверен в этом.
Сумит Трехан
1
Такая структура жестко закодирована в инструментах Spring сервлетов, в весеннем веб-приложении всегда есть как минимум два контекста приложения, смотрите обновленный ответ, надеюсь, это поможет.
Борис Треухов
Отличное описание. У меня были некоторые сомнения в этом сценарии. Поскольку я на начальном этапе, я нашел ваш полезный ответ для получения некоторых знаний ..
user533
msgstr "обязательный компонент будет выбран из родительского контекста, если он не присутствует в текущем контексте приложения". Можете ли вы объяснить, как? Как контекст веб-приложения может обращаться к bean-компонентам в контексте корневого приложения? Ссылка на какой-нибудь пример?
Anir
Привет @BorisTreukhov, Мое понимание таково: даже если мы не настроим «contextConfigLocation» в приложении MVC, корневой ApplicationContext все равно будет создан / создан без какого-либо набора конфигурации. Таким образом, мы можем сказать, что Spring Web-приложение имеет по крайней мере два контекста, созданных по умолчанию: One WebApplicationContext и One Root ApplicationContext. Пожалуйста, поправьте меня, если я ошибаюсь. Спасибо!
Декстер
14

Возвращаясь к дням сервлетов, web.xml может иметь только один <context-param>, поэтому при загрузке приложения сервером создается только один объект контекста, и данные в этом контексте распределяются между всеми ресурсами (например, сервлетами и JSP). Это то же самое, что иметь имя драйвера базы данных в контексте, которое не изменится. Аналогичным образом, когда мы объявляем contextConfigLocation param в <contex-param>Spring, создается один объект Application Context.

 <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>com.myApp.ApplicationContext</param-value>
 </context-param>

Вы можете иметь несколько сервлетов в приложении. Например, вы можете обрабатывать / secure / * запросы одним способом и / non-seucre / * другим способом. Для каждого из этих сервлетов у вас может быть объект контекста, который представляет собой WebApplicationContext.

<servlet>
    <servlet-name>SecureSpringDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>com.myapp.secure.SecureContext</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>SecureSpringDispatcher</servlet-name>
    <url-pattern>/secure/*</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>NonSecureSpringDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>com.myapp.non-secure.NonSecureContext</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>NonSecureSpringDispatcher</servlet-name>
    <url-pattern>/non-secure/*</url-patten>
</servlet-mapping>
Бен Теннисон
источник
14

Принятый ответ исчерпан, но на это есть официальное объяснение:

WebApplicationContext является расширением простого ApplicationContext, который имеет некоторые дополнительные функции, необходимые для веб-приложений. Он отличается от обычного ApplicationContext тем, что способен разрешать темы (см. Использование тем) и знает, с каким сервлетом он связан (имея ссылку на ServletContext). WebApplicationContext связан с ServletContext, и с помощью статических методов класса RequestContextUtils вы всегда можете найти WebApplicationContext, если вам нужен доступ к нему.

Цитируется из ссылки на веб-фреймворк Spring

Кстати, сервлет и корневой контекст оба являются webApplicationContext:

Типичная контекстная иерархия в Spring Web MVC

Ник Аллен
источник
хорошее объяснение.
Шашанк
6

ApplicationContext (корневой контекст приложения). Каждое веб-приложение Spring MVC имеет файл applicationContext.xml, который настроен как корневой каталог конфигурации контекста. Spring загружает этот файл и создает applicationContext для всего приложения. Этот файл загружается ContextLoaderListener, который настроен как параметр контекста в файле web.xml. И будет только один applicationContext для каждого веб-приложения.

WebApplicationContext: WebApplicationContext - это контекст приложения с веб-поддержкой, т. Е. Он содержит информацию о контексте сервлета. Одно веб-приложение может иметь несколько WebApplicationContext, и каждый сервлет Dispatcher (являющийся фронт-контроллером архитектуры Spring MVC) связан с WebApplicationContext. Файл конфигурации webApplicationContext * -servlet.xml является специфическим для DispatcherServlet. А поскольку в веб-приложении может быть настроено несколько сервлетов-диспетчеров для обслуживания нескольких запросов, в веб-приложении может быть несколько файлов webApplicationContext.

Хетал Рах
источник
3

Контекст веб-приложения , указанный WebApplicationContextинтерфейсом, является контекстом приложения Spring для веб-приложений. Он имеет все свойства обычного контекста приложения Spring, учитывая, что WebApplicationContextинтерфейс расширяет ApplicationContextинтерфейс, и добавляет метод для извлечения стандартного API сервлета ServletContextдля веб-приложения.

В дополнение к стандартным областям применения bean-компонентов Spring singletonи prototypeтри дополнительных области доступны в контексте веб-приложения:

  • request- ограничивает определение одного бина жизненным циклом одного HTTP-запроса; то есть каждый HTTP-запрос имеет свой собственный экземпляр компонента, созданного на основе определения одного компонента
  • session - ограничивает определение одного бина жизненным циклом сеанса HTTP
  • application - определяет единственное определение bean-компонента для жизненного цикла ServletContext
DimaSan
источник