Spring: parameters d’initialisation namespace vs contextConfigLocation dans web.xml

Je lis la documentation de Spring MVC et j’ai une question concernant les parameters init. J’utilise Spring 3.2 si c’est important. Quelle est la différence entre contextConfigLocation et namespace? Est-ce que contextConfigLocation est uniquement destiné à spécifier les dossiers dans lesquels la classe de contexte peut trouver une définition XML et l’atsortingbut namespace est destiné à spécifier le nom du fichier?

 AppServlet org.springframework.web.servlet.DispatcherServlet  contextConfigLocation WEB-INF   namespace application-context.xml  1  

Est-ce correct? Doit-il utiliser /WEB-INF/application-context.xml? Et devriez-vous spécifier des chemins?

TL; DR

Il vous suffit de définir la ou les valeurs de contextConfigLocation chaque fois que vous devez spécifier des fichiers de configuration personnalisés. De cette façon, vous spécifiez les noms des fichiers de configuration et leurs emplacements.

L’ namespace est essentiellement une méthode alternative pour indiquer à la classe du chargeur de contexte du conteneur Spring quel fichier de configuration utiliser. Je ne m’en contextConfigLocation jamais, mais utilisez simplement contextConfigLocation chaque fois que j’ai besoin de configurer des fichiers de configuration personnalisés.

Voici un exemple d’un de mes précédents projets de spring (certaines des configurations ont été omises par souci de concision):

web.xml

   Spring Web Application example   org.springframework.web.context.ContextLoaderListener   contextConfigLocation  /WEB-INF/spring/jdbc/spring-jdbc.xml /WEB-INF/spring/security/spring-security-context.xml     spring-mvc org.springframework.web.servlet.DispatcherServlet  contextConfigLocation  /WEB-INF/spring/mvc/spring-mvc-servlet.xml     spring-mvc /admin/*   

Longue réponse

OK, commençons par quelques moments importants. Il existe deux types de contextes avec lesquels nous traitons:

  1. contexte racine (parent)
  2. contexte de servlet individuel (enfant)

Citation de l’API Spring Framework (version 3.2.2 au moment de la rédaction de ce document) pour WebApplicationContext (mise en évidence):

Comme les contextes d’application génériques, les contextes d’application Web sont hiérarchiques. Il existe un seul contexte racine par application, tandis que chaque servlet de l’application (y compris un servlet du dissortingbuteur dans le cadre MVC) possède son propre contexte enfant .

Aussi ici: Les hiérarchies de contexte :

Par exemple, si vous développez une application Web Spring MVC, vous aurez généralement un WebApplicationContext racine chargé via ContextLoaderListener de Spring et un enfant WebApplicationContext chargé via le DispatcherServlet de Spring . Il en résulte une hiérarchie de contexte parent-enfant dans laquelle les composants partagés et la configuration de l’infrastructure sont déclarés dans le contexte racine et consommés dans le contexte enfant par des composants spécifiques au Web.

Et ici: 17.2 Le DispatcherServlet :

Les instances ApplicationContext au spring peuvent être étendues. Dans le framework Web MVC, chaque DispatcherServlet a son propre WebApplicationContext, qui hérite de tous les beans déjà définis dans la racine WebApplicationContext . Ces beans hérités peuvent être remplacés dans la scope spécifique à la servlet et vous pouvez définir de nouveaux beans spécifiques à la scope pour une instance de servlet donnée.

Voyons maintenant la configuration du contexte d’application racine . Voici un exemple:
web.xml

    org.springframework.web.context.ContextLoaderListener   contextConfigLocation  /WEB-INF/spring/daoContext.xml /WEB-INF/spring/applicationContext.xml    

De la documentation officielle du spring (accent mis sur le mien):
5.14.4 Instanciation pratique d’ApplicationContext pour les applications Web :

Vous pouvez créer des instances ApplicationContext de manière déclarative en utilisant, par exemple, un ContextLoader. Bien sûr, vous pouvez également créer des instances ApplicationContext par programmation en utilisant l’une des implémentations ApplicationContext.

Vous pouvez enregistrer un ApplicationContext à l’aide de ContextLoaderListener (voir l’exemple ci-dessus)

L’écouteur inspecte le paramètre contextConfigLocation. Si le paramètre n’existe pas, l’écouteur utilise /WEB-INF/applicationContext.xml par défaut . Lorsque le paramètre existe, l’écouteur sépare la chaîne à l’aide de délimiteurs prédéfinis (virgule, point-virgule et espace) et utilise les valeurs comme emplacements de recherche des contextes d’application. Les modèles de chemin de style Ant sont également pris en charge. Les exemples sont /WEB-INF/*Context.xml pour tous les fichiers dont le nom se termine par “Context.xml”, résidant dans le répertoire “WEB-INF” et /WEB-INF/**/*Context.xml, pour tous. ces fichiers dans n’importe quel sous-répertoire de “WEB-INF”.

Très souvent, la configuration du spring est divisée en plusieurs fichiers. C’est plus logique et pratique, surtout dans les projets à grande échelle. Dans notre exemple, nous avons explicitement défini deux fichiers XML de configuration: daoContext.xml et applicationContext.xml à l’emplacement personnalisé: /WEB-INF/spring/ . Encore une fois, si nous n’avions pas défini contextConfigLocation , ContextLoaderListener tenterait de localiser le fichier de configuration par défaut: /WEB-INF/applicationContext.xml .

REMARQUE:
Le contexte racine est facultatif . Voir aussi cette réponse: https://stackoverflow.com/a/7451389/814702

Donc, si le fichier de configuration par défaut /WEB-INF/applicationContext.xml ne correspond pas à vos besoins, utilisez ContextLoaderListener avec contextConfigLocation où vous pouvez définir des fichiers de configuration personnalisés pour définir le contexte de l’application racine .

Voyons ensuite le contexte de l’application individuelle (enfant) . De la documentation officielle du spring (accent mis sur le mien):
17.2 Le DispatcherServlet

Lors de l’initialisation d’un DispatcherServlet, Spring MVC recherche un fichier nommé
[nom-servlet] -servlet.xml dans le répertoire WEB-INF de votre application Web et crée les beans définis ici, en remplaçant les définitions des beans définis avec le même nom dans la scope globale.

Considérez la configuration suivante du Servlet DispatcherServlet (dans le fichier web.xml):

   golfing org.springframework.web.servlet.DispatcherServlet 1   golfing /golfing/*   

À propos de contextConfigLocation et de l’espace de noms

De la documentation (emphase la mienne):

Avec la configuration Servlet ci-dessus en place, vous devrez avoir un fichier appelé
/WEB-INF/golfing-servlet.xml dans votre application; Ce fichier contiendra tous vos composants Spring Web MVC spécifiques (beans). Vous pouvez modifier l’emplacement exact de ce fichier de configuration via un paramètre d’initialisation Servlet (voir ci-dessous pour plus de détails).

Vous pouvez personnaliser des instances DispatcherServlet individuelles en ajoutant des parameters d’initialisation Servlet (éléments init-param) à la déclaration Servlet dans le fichier web.xml. Voir le tableau suivant pour la liste des parameters pris en charge.

  • contextClass : Classe qui implémente WebApplicationContext, qui instancie le contexte utilisé par cette servlet. Par défaut, le XmlWebApplicationContext est utilisé.

  • contextConfigLocation : Chaîne transmise à l’instance de contexte (spécifiée par contextClass) pour indiquer où le ou les contextes peuvent être trouvés. La chaîne se compose potentiellement de plusieurs chaînes (en utilisant une virgule comme délimiteur) pour prendre en charge plusieurs contextes. Dans le cas de plusieurs emplacements de contexte avec des beans définis deux fois, le dernier emplacement est prioritaire.

  • namespace : Espace de noms du WebApplicationContext. La valeur par défaut est [servlet-name] -servlet.

Maintenant, étudions la documentation de l’API pour les classes associées. La classe DispatcherServlet étend la classe abstraite FrameworkServlet . À partir des documents de l’API FrameworkServlet (c’est moi qui souligne):

Transmet une servlet “contextConfigLocation” init-param à l’instance de contexte, en l’analysant en plusieurs chemins de fichier potentiellement séparés par un nombre illimité de virgules et d’espaces, comme
“test-servlet.xml, myServlet.xml”. Si elle n’est pas explicitement spécifiée, l’implémentation de contexte est supposée créer un emplacement par défaut à partir de l’espace de noms du servlet .

L’espace de noms par défaut est “‘servlet-name’-servlet”, par exemple “test-servlet” pour un nom de servlet “test” (menant à un emplacement par défaut “/WEB-INF/test-servlet.xml” avec XmlWebApplicationContext). L’espace de noms peut également être défini explicitement via le servlet init-param de l’espace de noms .

Voici l’extrait du code source de FrameworkServlet :
FrameworkServlet.java

 .... /** * Suffix for WebApplicationContext namespaces. If a servlet of this class is * given the name "test" in a context, the namespace used by the servlet will * resolve to "test-servlet". */ public static final Ssortingng DEFAULT_NAMESPACE_SUFFIX = "-servlet"; .... 

La classe de contexte par défaut pour FrameworkServlet est XmlWebApplicationContext . A partir de la documentation de l’ API XmlWebApplicationContext (mise en évidence de la mienne):

Par défaut, la configuration sera prise depuis “/WEB-INF/applicationContext.xml” pour le contexte racine et “/WEB-INF/test-servlet.xml” pour un contexte avec l’espace de noms “test-servlet” (comme pour une instance de DispatcherServlet avec le nom de servlet “test”).

Les parameters par défaut de l’emplacement de configuration peuvent être remplacés par le paramètre contextuel “contextConfigLocation” de ContextLoader et le paramètre init-servlet de FrameworkServlet . Les emplacements de configuration peuvent indiquer des fichiers concrets tels que “/WEB-INF/context.xml” ou des modèles de style Ant tels que “/WEB-INF/*-context.xml” (voir javadoc PathMatcher pour plus de détails sur les modèles).

contextConfigLocation emplacements de configuration par défaut à l’aide de contextConfigLocation est le même que dans l’exemple ci-dessus pour le contexte d’application racine.

En ce qui concerne le remplacement de l’espace de noms par défaut, il y a quelques moments importants. Lorsque vous définissez un nouvel espace de noms, ne l’ajoutez pas avec /WEB-INF et ne lui ajoutez pas de fichier .xml . La raison de cela peut être découverte si nous recherchons dans le fichier source la classe XmlWebApplicationContext :
XmlWebApplicationContext.java

 ... /** Default config location for the root context */ public static final Ssortingng DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml"; /** Default prefix for building a config location for a namespace */ public static final Ssortingng DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/"; /** Default suffix for building a config location for a namespace */ public static final Ssortingng DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml"; ... /** * The default location for the root context is "/WEB-INF/applicationContext.xml", * and "/WEB-INF/test-servlet.xml" for a context with the namespace "test-servlet" * (like for a DispatcherServlet instance with the servlet-name "test"). */ @Override protected Ssortingng[] getDefaultConfigLocations() { if (getNamespace() != null) { return new Ssortingng[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX}; } else { return new Ssortingng[] {DEFAULT_CONFIG_LOCATION}; } } 

Comme vous pouvez le voir, le code source dit tout.

Exemple de spécification d’un espace de noms personnalisé

web.xml

     spring-mvc org.springframework.web.servlet.DispatcherServlet  namespace spring/mvc/spring-mvc    spring-mvc /*   

Le résultat est que, au lieu d’utiliser l’espace de noms par défaut pour construire le chemin du fichier de configuration, ce serait /WEB-INF/spring-mvc-servlet.xml , le conteneur recherchera /WEB-INF/spring/mvc/spring-mvc.xml .

REMARQUE:
Les explications ci-dessus relatives au paramètre d’espace de noms personnalisé concernent la classe de contexte XmlWebApplicationContext par défaut. On peut spécifier une classe alternative, comme AnnotationConfigWebApplicationContext , il y aura donc des moments spéciaux pour cela.


CONCLUSION

Il est beaucoup plus facile d’utiliser le paramètre contextConfigLocation pour définir des fichiers de configuration personnalisés, à la fois pour le contexte d’application racine et pour les contextes individuels. La seule différence est que, pour le contexte d’application racine, vous utilisez dans l’élément , mais PAS dans un servlet spécifique (n’oubliez pas non plus la classe d’écouteur). Et pour le contexte enfant, utilisez nested dans l’élément pour chaque servlet spécifique . Voir mes configurations d’exemple ( web.xml ) au tout début de ce post.

Sources supplémentaires (comme si ce qui précède ne suffisait pas :-)):

  • Documentation de référence du framework Spring
  • Spring MVC Contexte Chargement

Voir aussi ces réponses:

  • Différence entre applicationContext.xml et spring-servlet.xml au spring
  • Quelle est la différence entre ApplicationContext et WebApplicationContext dans Spring MVC?
  • Spring-MVC: Qu’est-ce qu’un “contexte” et un “espace de noms”?

Je pense que la réponse de LuckyLuke contient beaucoup d’informations utiles, mais elle ne répond pas à la question. En particulier, comment les parameters “namespace” et “contextConfigLocation” fonctionnent-ils ensemble?

Le seul endroit où je peux trouver la réponse concrète est le code source:

  • Paremeter d’ espace de noms définit un espace de noms personnalisé à utiliser pour créer un emplacement de configuration de contexte par défaut
  • Le paramètre contextConfigLocation définit explicitement l’emplacement de configuration du contexte, au lieu de compter sur l’emplacement par défaut créé à partir de l’espace de noms.

Quelle est la différence entre contextConfigLocation et namespace? contextConfigLocation est utilisé pour spécifier le chemin des fichiers de configuration de spring, ce qui signifie qu’ils seront initialisés. namespace est utilisé pour spécifier le chemin et le nom du DispatcherServlet de Spring MVC. la valeur par défaut est [Dispatcher_name]-servlet.xml , voici un exemple:

  dispatcher org.springframework.web.servlet.DispatcherServlet  namespace config/spring-mvc  1  

Spring recherchera un fichier à utiliser comme configuration mvc par le chemin de /WEB-INF/config/spring-mvc.xml .
Est-ce que contextConfigLocation est uniquement destiné à spécifier les dossiers dans lesquels la classe de contexte peut trouver une définition XML?

  contextConfigLocation /WEB-INF/config/app-*.xml  

Le code ci-dessus montre que lorsque l’application au démarrage de Spring charge tous les fichiers dont le nom commence par «app-» et se termine par «.xml» dans le répertoire WEB-INF / config.

Doit-il utiliser /WEB-INF/application-context.xml? Et devriez-vous spécifier des chemins?
Grâce à l’exemple ci-dessus, nous pouvons savoir que lors de la configuration de Spring, nous devons spécifier le chemin complet et le nom de fichier générique et que SpringMVC uniquement doit spécifier le chemin (s’il se trouve dans (n’incluez pas l’extension).
En espérant vous aider 🙂