web-dev-qa-db-fra.com

Rôle / objectif de ContextLoaderListener in Spring?

J'apprends Spring Framework qui est utilisé dans mon projet. J'ai trouvé l'entrée ContextLoaderListener dans mon web.xml fichier. Mais ne pouvait pas comprendre comment exactement cela aide un développeur?

Dans la documentation officielle de ContextLoaderListener , il est indiqué qu'il doit démarrer WebApplicationContext . À propos de WebApplicationContext JavaDocs dit:

Interface permettant de configurer une application Web.


Mais je ne suis pas en mesure de comprendre ce que je réalise avec ContextLoaderListener qui initialise en interne le WebApplicationContext ?

Selon ma compréhension , ContextLoaderListener lit le fichier de configuration Spring (avec une valeur donnée par rapport à contextConfigLocation dans web.xml), le analyse et charge le bean singleton défini dans ce fichier de configuration. De même, lorsque nous voulons charger le prototype de bean , nous utiliserons le même contexte d'application Web pour le charger. Nous initialisons donc l'application Web avec ContextLoaderListener afin de pouvoir lire/analyser/valider le fichier de configuration à l'avance et, chaque fois que nous souhaitons injecter une dépendance, nous pouvons le faire sans délai. Cette compréhension est-elle correcte?

160
M Sach

Votre compréhension est correcte. ApplicationContext est l'endroit où vivent vos haricots Spring. ContextLoaderListener a un double objectif:

  1. pour lier le cycle de vie de ApplicationContext au cycle de vie de ServletContext et

  2. pour automatiser la création de ApplicationContext, de sorte que vous n'ayez pas à écrire de code explicite pour le créer - c'est une fonction pratique.

Une autre chose pratique à propos de ContextLoaderListener est qu’il crée un WebApplicationContext et WebApplicationContext permet d’accéder au ServletContext via ServletContextAware beans et la méthode getServletContext.

103
sourcedelica

ContextLoaderListener est facultatif . Juste pour faire un point ici: vous pouvez démarrer une application Spring sans jamais configurer ContextLoaderListener, juste un minimum de base web.xml avec DispatcherServlet.

Voici à quoi cela ressemblerait:

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>

Créez un fichier nommé dispatcher-servlet.xml et stockez-le sous WEB-INF. Puisque nous avons mentionné index.jsp dans la liste de bienvenue, ajoutez ce fichier sous WEB-INF.

dispatcher-servlet.xml

Dans le dispatcher-servlet.xml définissez vos 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>
41
Vikram

Pour une application Spring simple, vous n'avez pas besoin de définir ContextLoaderListener dans votre web.xml; vous pouvez simplement mettre tous vos fichiers de configuration Spring dans <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>

Pour une application Spring plus complexe, dans laquelle vous avez défini plusieurs DispatcherServlet, vous pouvez avoir les fichiers de configuration Spring communs partagés par tous les DispatcherServlet définis dans le 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>

Gardez simplement à l'esprit que ContextLoaderListener effectue le travail d'initialisation proprement dit pour le contexte d'application racine .

J'ai trouvé cet article qui aide beaucoup: Spring MVC - Contexte de l'application vs Contexte de l'application Web

23
xli

Le blog " Objectif de ContextLoaderListener - Spring MVC " donne une très bonne explication.

Selon lui, les contextes d'application sont hiérarchiques et le contexte de DispatcherSerlvet devient donc l'enfant du contexte de ContextLoaderListener. De ce fait, la technologie utilisée dans la couche de contrôleur (Struts ou Spring MVC) peut être indépendante du contexte racine créé par ContextLoaderListener.

10
Dileepa

Lorsque vous souhaitez placer votre fichier Servlet dans votre emplacement personnalisé ou avec un nom personnalisé, plutôt que la convention de dénomination par défaut [servletname]-servlet.xml et le chemin sous Web-INF/, vous pouvez utiliser ContextLoaderListener.

3
Dungeon_master

ContextLoaderListner est un écouteur de servlet qui charge tous les différents fichiers de configuration (configuration de la couche de service, configuration de la couche de persistance, etc.) dans un contexte d'application à ressort unique.

Cela permet de fractionner les configurations de ressort sur plusieurs fichiers XML.

Une fois les fichiers de contexte chargés, Spring crée un objet WebApplicationContext basé sur la définition du bean et le stocke dans le ServletContext de votre application Web.

3
Prashant_M

enter image description here Ce Bootstrap écouteur doit démarrer et arrêter la racine de Spring WebApplicationContext. Comme une application Web peut avoir plusieurs servlets de distributeur et chacun ayant son propre contexte d’application contenant des contrôleurs, un résolveur de vues, des mappages de gestionnaires, etc. contexte d’application créé par les servlets de répartiteur).

La deuxième utilisation de cet écouteur est lorsque vous souhaitez utiliser la sécurité de printemps.

2
rulhaniam

En gros, vous pouvez isoler votre contexte d'application racine et votre contexte d'application Web à l'aide de ContextLoaderListner.

Le fichier de configuration mappé avec le paramètre context se comportera comme une configuration de contexte d'application racine. Et le fichier de configuration mappé avec dispatcher servlet se comportera comme un contexte d'application Web.

Dans toute application Web, nous pouvons avoir plusieurs servlets de distributeur, donc plusieurs contextes d'application Web.

Cependant, dans toute application Web, nous ne pouvons avoir qu'un seul contexte d'application racine partagé avec tous les contextes d'application Web.

Nous devrions définir nos services communs, entités, aspects, etc. dans le contexte d'application racine. Et les contrôleurs, intercepteurs, etc. sont dans le contexte d'application Web pertinent.

Un exemple de fichier web.xml est

<!-- 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> 

Ici, la classe de configuration example.config.AppConfig peut être utilisée pour configurer des services, des entités, des aspects, etc. dans un contexte d'application racine qui sera partagé avec tous les autres contextes d'application Web (par exemple, nous avons deux classes de configuration de contexte d'application Web RestConfig et WebConfig).

PS: Ici, ContextLoaderListener est complètement facultatif. Si nous ne mentionnons pas ContextLoaderListener dans le fichier web.xml, AppConfig ne fonctionnera pas. Dans ce cas, nous devons configurer tous nos services et entités dans WebConfig et Rest Config.

2
Anil Agrawal

Classe d'écoute - Écoute d'un événement (par exemple .. Démarrage/arrêt du serveur)

ContextLoaderListener -

  1. Écoute lors du démarrage/arrêt du serveur
  2. Prend les fichiers de configuration Spring en entrée et crée les beans conformément à la configuration et les prépare (détruit le bean lors de l'arrêt)
  3. Les fichiers de configuration peuvent être fournis comme ceci dans web.xml

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

Cela vous donnera le point de raccordement pour mettre le code que vous souhaitez exécuter sur le déploiement de l'application Web

1
Jigar Joshi

Si nous écrivons web.xml sans ContextLoaderListener, nous ne pouvons pas donner l'athuntication à l'aide de customAuthenticationProvider dans la sécurité printanière. Etant donné que DispatcherServelet est le contexte enfant de ContextLoaderListener, customAuthenticationProvider est la partie de parentContext qui est ContextLoaderListener. Le contexte parent ne peut donc pas avoir les dépendances du contexte enfant. Il est donc recommandé d'écrire spring-context.xml dans contextparam au lieu de l'écrire dans initparam.

0
SathishSakthi

Je crois que son utilisation réelle vient lorsque vous voulez avoir plusieurs fichiers de configuration ou que vous avez un fichier xyz.xml au lieu de applicationcontext.xml, par exemple.

<context-param><param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/training-service.xml, /WEB-INF/training-data.xml</param-value> </context-param>

Une autre approche de ContextLoaderListener utilise ContextLoaderServlet comme ci-dessous.

<servlet> <servlet-name>context</servlet-name> <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>

0
user666

Dans le contexte de la structure de ressort, ContextLoaderListener permet de charger les autres beans de votre application, tels que les composants de couche intermédiaire et de couche de données qui gèrent le back-end de l'application.

0
Salahin Rocky

Votre compréhension est correcte. Je me demande pourquoi vous ne voyez aucun avantage dans ContextLoaderListener. Par exemple, vous devez créer une fabrique de sessions (pour gérer la base de données). Cette opération peut prendre un certain temps, il est donc préférable de la lancer au démarrage. Bien sûr, vous pouvez le faire avec des servlets init ou autre chose, mais l'avantage de l'approche de Spring est que vous effectuez une configuration sans écrire de code.

0
evg