Роль/Цель ContextLoaderListener в Spring?
Я изучаю Spring Framework, который используется в моем проекте. Я нашел запись ContextLoaderListener в моем файле web.xml. Но не мог понять, как именно это помогает разработчику?
В официальной документации ContextLoaderListener говорится, что для запуска WebApplicationContext. Относительно WebApplicationContext JavaDocs говорят:
Интерфейс для настройки конфигурации для веб-приложения.
Но я не могу понять, что я достигаю с помощью ContextLoaderListener, который внутренне инициализирует WebApplicationContext?
В соответствии с моим пониманием ContextLoaderListener считывает конфигурационный файл Spring (со значением, заданным для contextConfigLocation в web.xml), анализирует его и загружает singleton bean, определенный в этом файле конфигурации. Аналогично, когда мы хотим загрузить прототип bean, мы будем использовать тот же контекст webapplication для его загрузки. Таким образом, мы инициализируем web-приложение с помощью ContextLoaderListener, чтобы мы заранее читали/разбирали/проверяли файл конфигурации, и всякий раз, когда мы пытались внедрить зависимость, мы можем сделать это без задержки. Правильно ли это понимание?
Ответы
Ответ 1
Ваше понимание верное. ApplicationContext
находится в вашем Spring beans. Цель ContextLoaderListener
- двукратная:
-
чтобы связать жизненный цикл ApplicationContext
с жизненным циклом ServletContext
и
-
чтобы автоматизировать создание ApplicationContext
, поэтому вам не нужно писать явный код для его создания - это удобная функция.
Еще одна удобная вещь о ContextLoaderListener
заключается в том, что она создает WebApplicationContext
и WebApplicationContext
предоставляет доступ к ServletContext
через ServletContextAware
beans и getServletContext
.
Ответ 2
ContextLoaderListener
является необязательным. Для этого нужно сделать следующее: вы можете загрузить приложение Spring, не настраивая ContextLoaderListener
, просто базовый минимум web.xml
с DispatcherServlet
.
Вот как это выглядит:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID"
version="2.5">
<display-name>Some Minimal Webapp</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
Создайте файл с именем dispatcher-servlet.xml
и сохраните его под WEB-INF
. Поскольку мы упоминали index.jsp
в списке приветствия, добавьте этот файл под WEB-INF
.
диспетчер-servlet.xml
В dispatcher-servlet.xml
укажите beans:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="bean1">
...
</bean>
<bean id="bean2">
...
</bean>
<context:component-scan base-package="com.example" />
<!-- Import your other configuration files too -->
<import resource="other-configs.xml"/>
<import resource="some-other-config.xml"/>
<!-- View Resolver -->
<bean
id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property
name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
Ответ 3
Для простого приложения Spring вам не нужно определять ContextLoaderListener
в web.xml
; вы можете просто поместить все ваши файлы конфигурации Spring в <servlet>
:
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/mvc-core-config.xml, classpath:spring/business-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Для более сложного приложения Spring, где у вас установлено несколько DispatcherServlet
, вы можете иметь общие файлы конфигурации Spring, которые совместно используются всеми DispatcherServlet
, определенными в ContextLoaderListener
:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/common-config.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>mvc1</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/mvc1-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>mvc2</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/mvc2-config.xmll</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Просто имейте в виду, ContextLoaderListener
выполняет фактическую работу по инициализации для контекста приложения root.
Я нашел, что эта статья помогает много:
Spring MVC - Контекст приложения и контекст веб-приложения
Ответ 4
Блог " Цель ContextLoaderListener - Spring MVC" дает очень хорошее объяснение.
В соответствии с этим приложения-контексты являются иерархическими и, следовательно, контекст DispatcherSerlvet становится дочерним элементом контекста ContextLoaderListener. Благодаря этому технология, используемая в уровне контроллера (Struts или Spring MVC), может независимо от корневого контекста, созданного ContextLoaderListener.
Ответ 5
Если вы хотите поместить свой файл сервлета в свое пользовательское местоположение или с помощью специального имени, а не в соглашение об именах по умолчанию [servletname]-servlet.xml
и путь в Web-INF/
, вы можете использовать ContextLoaderListener
.
Ответ 6
В принципе вы можете изолировать свой контекст корневого приложения и контекст веб-приложения с помощью ContextLoaderListner.
Конфигурационный файл, сопоставленный с параметром context, будет вести себя как конфигурация контекста корневого приложения. И файл конфигурации, сопоставленный с сервлетом диспетчера, будет вести себя как контекст веб-приложения.
В любом веб-приложении у нас может быть несколько сервлетов диспетчера, поэтому несколько контекстов веб-приложений.
Но в любом веб-приложении у нас может быть только один контекст корневого приложения, общий доступ ко всем контекстам веб-приложений.
Мы должны определить наши общие службы, сущности, аспекты и т.д. в контексте корневого приложения. И контроллеры, перехватчики и т.д. Находятся в соответствующем контексте веб-приложений.
Пример web.xml
<!-- language: xml -->
<web-app>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>example.config.AppConfig</param-value>
</context-param>
<servlet>
<servlet-name>restEntryPoint</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>example.config.RestConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>restEntryPoint</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>webEntryPoint</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>example.config.WebConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>webEntryPoint</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Здесь config-класс example.config.AppConfig может использоваться для настройки служб, сущностей, аспектов и т.д. в контексте корневого приложения, которые будут использоваться во всех других контекстах веб-приложений (например, здесь у нас есть два контекстных контекста веб-приложения RestConfig и WebConfig)
PS: Здесь ContextLoaderListener полностью необязателен. Если мы не укажем ContextLoaderListener в web.xml, AppConfig не будет работать. В этом случае нам необходимо настроить все наши службы и объекты в WebConfig и Rest Config.
Ответ 7
Это даст вам возможность перехватить код, который вы хотите выполнить при развертывании веб-приложения.
Ответ 8
Ваше понимание верное. Интересно, почему вы не видите никаких преимуществ в ContextLoaderListener. Например, вам нужно создать сеанс factory (для управления базой данных). Эта операция может занять некоторое время, поэтому лучше сделать это при запуске. Конечно, вы можете сделать это с помощью сервлетов init или чего-то еще, но преимущество подхода Spring заключается в том, что вы создаете конфигурацию без написания кода.
Ответ 9
Если мы напишем web.xml без ContextLoaderListener, мы не можем дать аттестацию с помощью customAuthenticationProvider в spring безопасности. Поскольку DispatcherServelet является дочерним контекстом ContextLoaderListener, customAuthenticationProvider является частью parentContext, который является ContextLoaderListener. Поэтому родительский контекст не может иметь зависимости дочернего контекста. И поэтому лучше всего писать spring -context.xml в contextparam вместо записи в initparam.
Ответ 10
Я считаю, что его реальное использование приходит, когда вы хотите иметь более одного файла конфигурации или у вас есть xyz.xml файл вместо applicationcontext.xml, например
<context-param><param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/training-service.xml,
/WEB-INF/training-data.xml</param-value>
</context-param>
Другой подход к ContextLoaderListener использует ContextLoaderServlet, как показано ниже
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
Ответ 11
Listener class - прослушивает событие (например, запуск/завершение сервера)
ContextLoaderListener -
Ответ 12
ContextLoaderListner - это прослушиватель сервлета, который загружает все различные файлы конфигурации (конфигурацию уровня обслуживания, конфигурацию уровня сохранения и т.д.) в один контекст приложения spring.
Это помогает разделить конфигурации spring на несколько XML файлов.
После загрузки файлов контекста spring создает объект WebApplicationContext на основе определения bean и сохраняет его в ServletContext вашего веб-приложения.
Ответ 13
В контексте spring основной целью ContextLoaderListener является загрузка другого beans в ваше приложение, такого как компоненты среднего уровня и уровня данных, которые управляют задним концом приложение.
Ответ 14
Этот слушатель Bootstrap должен запускаться и закрываться вниз Spring root WebApplicationContext. Поскольку веб-приложение может иметь несколько сервлетов диспетчера и каждый из них имеет свой собственный контекст приложения, содержащий контроллеры, просмотр разрешающего устройства, сопоставления обработчиков и т.д. Но вы можете иметь сервис beans, DAO beans в корневом контексте приложения и хотите использовать его во всех дочерний контекст приложения (контекст приложения, созданный сервлетами диспетчера).
Второе использование этого прослушивателя - это когда вы хотите использовать Spring безопасность.