web-dev-qa-db-fra.com

Fractionnement de ApplicationContext en plusieurs fichiers

Quelle est la bonne façon de diviser la configuration de Spring en plusieurs fichiers xml?

En ce moment j'ai

  • /WEB-INF/foo-servlet.xml
  • /WEB-INF/foo-service.xml
  • /WEB-INF/foo-persistence.xml

Ma web.xml a les caractéristiques suivantes:

<servlet>
    <description>Spring MVC Dispatcher Servlet</description>
    <servlet-name>intrafest</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/foo-*.xml
        </param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
</servlet>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
            /WEB-INF/foo-*.xml
    </param-value>
</context-param>


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

Les vraies questions:

  • Cette approche est-elle correcte/meilleure ?
  • Dois-je vraiment spécifier les emplacements de configuration à la fois dans le DispatcherServlet [~ # ~] et [~ # ~] le context-param sections?

Que dois-je garder à l'esprit pour pouvoir référencer les beans définis dans foo-servlet.xml de foo-service.xml? Est-ce que cela a quelque chose à voir avec la spécification de contextConfigLocation dans web.xml?

Mise à jour 1:

J'utilise Spring Framework 3.0. Je crois comprendre que je n'ai pas besoin d'importer des ressources comme ceci:

 <import resource="foo-services.xml"/> 

Est-ce une supposition correcte?

58
kosoant

Je trouve la configuration suivante la plus simple.

Utilisez le mécanisme de chargement du fichier de configuration par défaut DispatcherServlet :

Le framework recherchera, lors de l'initialisation d'un DispatcherServlet, un fichier nommé [nom-servlet] -servlet.xml dans le répertoire WEB-INF de votre application Web et créera les beans qui y sont définis (en remplaçant les définitions de tous les beans définis avec le même nom dans la portée globale).

Dans votre cas, créez simplement un fichier intrafest-servlet.xml dans le WEB-INF dir et n'a pas besoin de spécifier quoi que ce soit d'informations spécifiques dans web.xml.

Dans intrafest-servlet.xml fichier que vous pouvez utiliser import pour composer votre configuration XML.

<beans>
  <bean id="bean1" class="..."/>
  <bean id="bean2" class="..."/>

  <import resource="foo-services.xml"/>
  <import resource="foo-persistence.xml"/>
</beans>

Notez que l'équipe Spring préfère en fait charger plusieurs fichiers de configuration lors de la création du (Web) ApplicationContext. Si vous voulez toujours le faire de cette façon, je pense que vous n'avez pas besoin de spécifier les deux paramètres de contexte (context-param) et paramètres d'initialisation du servlet (init-param). L'un des deux fera l'affaire. Vous pouvez également utiliser des virgules pour spécifier plusieurs emplacements de configuration.

48
eljenso

Mike Nereson a ceci à dire sur son blog à:

http://blog.codehangover.com/load-multiple-contexts-into-spring/

Il y a plusieurs façons de faire ça.

1. web.xml contextConfigLocation

Votre première option consiste à les charger tous dans le contexte de votre application Web via l'élément ContextConfigLocation. Vous allez déjà avoir votre contexte d'application principal ici, en supposant que vous écrivez une application Web. Tout ce que vous devez faire est de mettre un espace blanc entre la déclaration du contexte suivant.

  <context-param>
      <param-name> contextConfigLocation </param-name>
      <param-value>
          applicationContext1.xml
          applicationContext2.xml
      </param-value>
  </context-param>

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

Ce qui précède utilise les retours chariot. Alternativement, vous pourriez simplement mettre un espace.

  <context-param>
      <param-name> contextConfigLocation </param-name>
      <param-value> applicationContext1.xml applicationContext2.xml </param-value>
  </context-param>

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

2. ressource d'importation applicationContext.xml

Votre autre option consiste à simplement ajouter votre applicationContext.xml principale au web.xml, puis à utiliser les instructions d'importation dans ce contexte principal.

Dans applicationContext.xml vous pourriez avoir…

  <!-- hibernate configuration and mappings -->
  <import resource="applicationContext-hibernate.xml"/>

  <!-- ldap -->
  <import resource="applicationContext-ldap.xml"/>

  <!-- aspects -->
  <import resource="applicationContext-aspects.xml"/>

Quelle stratégie devez-vous utiliser?

1. Je préfère toujours charger via web.xml .

Parce que cela me permet de garder tous les contextes isolés les uns des autres. Avec les tests, nous pouvons charger uniquement les contextes dont nous avons besoin pour exécuter ces tests. Cela rend également le développement plus modulaire car les composants restent loosely coupled, afin qu'à l'avenir je puisse extraire un package ou une couche verticale et le déplacer vers son propre module.

2. Si vous chargez des contextes dans un non-web application, J'utiliserais la ressource import.

27
Human Being

Nous avons affaire à deux types de contextes:

1: contexte racine (contexte parent. Inclut généralement toutes les initialisations jdbc (ORM, Hibernate) et autres configurations liées à la sécurité du ressort)

2: contexte de servlet individuel (contexte enfant.Context Dispatcher Servlet Context et initialise tous les beans liés à spring-mvc (contrôleurs, URL Mapping, etc.)).

Voici un exemple de web.xml qui inclut plusieurs fichiers de contexte d'application

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://Java.Sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://Java.Sun.com/xml/ns/javaee
                            http://Java.Sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <display-name>Spring Web Application example</display-name>

    <!-- Configurations for the root application context (parent context) -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/jdbc/spring-jdbc.xml <!-- JDBC related context -->
            /WEB-INF/spring/security/spring-security-context.xml <!-- Spring Security related context -->
        </param-value>
    </context-param>

    <!-- Configurations for the DispatcherServlet application context (child context) -->
    <servlet>
        <servlet-name>spring-mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/spring/mvc/spring-mvc-servlet.xml
            </param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/admin/*</url-pattern>
    </servlet-mapping>

</web-app>
13
user2815238

@eljenso: le contexte d'application Web intrafest-servlet.xml xml sera utilisé si l'application utilise SPRING WEB MVC.

Sinon, la configuration @kosoant est correcte.

Exemple simple si vous n'utilisez pas SPRING WEB MVC, mais souhaitez utiliser SPRING IOC:

Dans web.xml:

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:application-context.xml</param-value>
</context-param>

Ensuite, votre application-context.xml contiendra: <import resource="foo-services.xml"/> ces instructions d'importation pour charger divers fichiers de contexte d'application et les placer dans principal application-context.xml.

Merci et j'espère que cela vous aidera.

6
Sreeni

Je suis l'auteur de modular-spring-contexts .

Il s'agit d'une petite bibliothèque d'utilitaires pour permettre une organisation plus modulaire des contextes de printemps que celle obtenue en utilisant Composer des métadonnées de configuration basées sur XML . modular-spring-contexts fonctionne en définissant des modules, qui sont essentiellement des contextes d'application autonomes et en permettant aux modules d'importer des beans à partir d'autres modules, qui sont exportés dans leur module d'origine.

Les points clés sont alors

  • contrôle des dépendances entre modules
  • contrôle des haricots exportés et de l'endroit où ils sont utilisés
  • possibilité réduite de nommer les collisions de haricots

Un exemple simple ressemblerait à ceci:

Fichier moduleDefinitions.xml:

<?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:module="http://www.gitlab.com/SpaceTrucker/modular-spring-contexts"
    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.gitlab.com/SpaceTrucker/modular-spring-contexts xsd/modular-spring-contexts.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config />

    <module:module id="serverModule">
        <module:config location="/serverModule.xml" />
    </module:module>

    <module:module id="clientModule">
        <module:config location="/clientModule.xml" />
        <module:requires module="serverModule" />
    </module:module>

</beans>

Fichier serverModule.xml:

<?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:module="http://www.gitlab.com/SpaceTrucker/modular-spring-contexts"
    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.gitlab.com/SpaceTrucker/modular-spring-contexts xsd/modular-spring-contexts.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config />

    <bean id="serverSingleton" class="Java.math.BigDecimal" scope="singleton">
        <constructor-arg index="0" value="123.45" />
        <meta key="exported" value="true"/>
    </bean>

</beans>

Fichier clientModule.xml

<?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:module="http://www.gitlab.com/SpaceTrucker/modular-spring-contexts"
    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.gitlab.com/SpaceTrucker/modular-spring-contexts xsd/modular-spring-contexts.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config />

    <module:import id="importedSingleton" sourceModule="serverModule" sourceBean="serverSingleton" />

</beans>
1
SpaceTrucker