Роль/Цель 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 -

  • Слушает при запуске/завершении работы сервера
  • Принимает конфигурационные файлы Spring в качестве входных данных и создает beans в соответствии с конфигурацией и готовит ее (уничтожает bean во время выключения)
  • Конфигурационные файлы могут быть предоставлены как в web.xml

    <param-name>contextConfigLocation</param-name>  
    <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>  
    

Ответ 12

ContextLoaderListner - это прослушиватель сервлета, который загружает все различные файлы конфигурации (конфигурацию уровня обслуживания, конфигурацию уровня сохранения и т.д.) в один контекст приложения spring.

Это помогает разделить конфигурации spring на несколько XML файлов.

После загрузки файлов контекста spring создает объект WebApplicationContext на основе определения bean и сохраняет его в ServletContext вашего веб-приложения.

Ответ 13

В контексте spring основной целью ContextLoaderListener является загрузка другого beans в ваше приложение, такого как компоненты среднего уровня и уровня данных, которые управляют задним концом приложение.

Ответ 14

введите описание изображения здесь Этот слушатель Bootstrap должен запускаться и закрываться вниз Spring root WebApplicationContext. Поскольку веб-приложение может иметь несколько сервлетов диспетчера и каждый из них имеет свой собственный контекст приложения, содержащий контроллеры, просмотр разрешающего устройства, сопоставления обработчиков и т.д. Но вы можете иметь сервис beans, DAO beans в корневом контексте приложения и хотите использовать его во всех дочерний контекст приложения (контекст приложения, созданный сервлетами диспетчера).

Второе использование этого прослушивателя - это когда вы хотите использовать Spring безопасность.