41 votes

Aide / explication de la hiérarchie de configuration de fichier XML Spring

Quand j'ai commencé à apprendre à propos de Printemps, les choses ont été configurés dans le applicationContext.xml fichier. Puis, comme j'ai commencé à lire des livres spécifiquement sur les versions plus récentes de printemps, ils ont tous fait la configuration en XML distinct des fichiers tels que des myapp-servlet, xml, myapp-security.xml, myapp-service.xml, etc., par la configuration d'un contextConfigLocation dans le web.xml fichier. Ainsi, par exemple, le code que j'ai suivi avec a ce qu'il a contextConfigLocation:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/myapp-servlet.xml
        /WEB-INF/myapp-data.xml
    </param-value>
</context-param>

De toute façon, j'ai récemment rencontré un problème de configuration (que les gens utiles ici à StackOverflow m'a aidé à comprendre), en raison de cette séparation. Il n'y a pas de applicationContext.xml fichier pour les exemples de ces livres et plus tard, quand j'ai essayé d'ajouter balayage automatique et annotations à l'application de la présente cause des problèmes. J'ai essayé de déplacer le tout dans applicationContext.xml et les autres fichiers et qui a résolu le problème. Rien d'autre n'a changé, je viens de tout mettre dans applicationContext.xml.

Donc, ce, ainsi que les commentaires des autres, a conduit à me sorte de comprendre que, même si vous ne créez pas un applicationContext.xml il est encore utilisé et il est le très haut niveau d'une sorte de hiérarchie de configuration. J'espère que quelqu'un d'autre peut m'expliquer comment ça fonctionne car je n'ai pas trouvé d'explication sur elle n'importe où.

Ainsi, par exemple, si je mets certaines context:component-scan les balises dans les fichiers de configuration ci-dessous applicationContext.xml il pourrait causer certaines classes pour ne pas obtenir de numérisation. Les choses de cette nature. Je ne comprends pas la priorité et ce qui doit aller où pour être sûr que c'est vu de l'application de large et ainsi de suite. Si quelqu'un peut clairement expliquer ou m'indiquer une ressource qui explique que j'aimerais beaucoup l'apprécier, je vous remercie. Espérons que ce que je demande, de sens.

88voto

Ryan Stewart Points 46960

Il n'y a rien de spécial sur le fichier nommé "applicationContext.xml" sauf que c'est le nom de Printemps a tendance à attendre que son fichier de configuration par défaut. En utilisant un fichier nommé que ou plusieurs fichiers nommés "dog.xml", "cat.xml" et "alien.xml" fonctionnera exactement de la même manière. Les difficultés que vous rencontrez, c'est d'avoir plusieurs ApplicationContexts en usage à la même époque, pas d'avoir plusieurs fichiers XML. J'ai récemment répondu à quelques questions de la part des gens qui avaient des problèmes causés par la non compréhension de ces concepts. Découvrez ces réponses, et de voir quelles sont les questions que vous avez toujours:

Déclarant Printemps Bean dans le Contexte Parent vs Enfant Contexte

Spring-MVC: Quelles sont les "contexte" et "espace de noms"?

Edit: En réponse à votre nouvelle question:

J'ai eu un <context:component-scan base-package="com.myapp"/> balise dans mon servlet.xml.

Je suppose que ce "servlet.xml" le fichier est nommé comme foo-servlet.xml, où la DispatcherServlet configuré dans votre web.xml est nommé "toto", comme

<servlet>
    <servlet-name>foo</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>

Par convention, lorsque cette DispatcherServlet démarre, il va créer un nouveau ApplicationContext configuré par le fichier foo-servlet.xml, dérivé de l' servlet-name. Maintenant, puisque tu mettre un context:component-scan là, il va analyser récursivement le paquet et de créer des haricots pour toutes les classes annotées. Le package que vous avez donné, com.myapp, on dirait qu'il est le package de base pour l'ensemble de votre application, de sorte que le Printemps va créer des haricots de toutes les classes annotées dans votre application, y compris l'accès aux données dans ce un ApplicationContext qui est associé à la DispatcherServlet. Généralement, ce contexte ne devrait avoir vue la couche des trucs et des haricots qui soutiennent directement la DispatcherServlet en elle, donc c'était quelque chose d'une mauvaise configuration.

Dans mon data.xml fichier, j'ai eu de la source de données haricots et qu'il a été. Pas d'autres haricots, tout le reste était autocâblés et annoté.

Sans doute, cette "data.xml" le fichier est celui que vous avez énumérés dans l' contextConfigLocation context-param. En supposant que vous souhaitez également ajouté la ContextLoaderListener à votre web.xml, comme

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

alors ce fichier sera utilisé pour créer un deuxième ApplicationContext--le contexte de la racine. C'est ce que cet auditeur n'. Notez qu'il fait construit le contexte de tous les fichiers listés en contextConfigLocation, et si, vous aussi inclus votre "servlet.xml" dans cette liste, vous avez chargé cette configuration à deux reprises: ici, dans le contexte de la racine ainsi que dans le contexte associé à la DipatcherServlet. J'espère que vous voyez maintenant comment il y a une nette séparation entre les fichiers de configuration XML et le ApplicationContexts que de la configuration. Le même fichier XML peut facilement être utilisé pour configurer les deux contextes différents. Si cela est correct ou pas est une autre question. Dans ce cas particulier, il n'est pas.

La commande que j'ai décrit ces deux contextes est en fait à l'envers. J'étais juste à la suite de votre description de ce que vous avez fait. Le ContextLoaderListener, étant un ServletContextListener, sera toujours exécuté avant une servlet démarre. Cela signifie que le contexte de la racine est créé en premier, et l'autre contexte seconde. C'est par la conception de sorte que lorsque la DispatcherServlet crée son contexte, il peut ajouter qu'à l'enfant de la racine de contexte. J'ai décrit cette relation dans les autres postes. L'effet le plus important de ce que les haricots dans le contexte de la racine sont disponibles et par la DispatcherServlet du contexte. Qui s'applique à autocâblés relations, trop. C'est important, car la DispatcherServlet seulement ressemble dans son contexte associé pour les haricots dont il a besoin, comme les instances du contrôleur. Vos contrôleurs, même si, à l'évidence être câblé avec l'appui des haricots. Ainsi, traditionnellement, les contrôleurs de vivre dans la DispatcherServlet du contexte, et de soutien des haricots vivent dans le contexte de la racine.

J'ai ensuite essayé d'ajouter @Transacational à mon service bean et il ne serait pas persister.

Pour @Transactional de travail, vous devez inclure l' <tx:annotation-driven/> balise dans la configuration de l'ApplicationContext où la annoté bean vie. Le truc est de savoir "d'où il vit" une partie. Les haricots dans un enfant peut remplacer les haricots dans un contexte parent. Donc, je suis juste deviner ici-si vous avez chargé tous vos haricots dans la DispatcherServlet contexte que j'ai décrit ci-dessus, mais mettre l' <tx:annotation-driven/> dans le contexte de la racine, vous pourriez avoir un haricot dans le contexte de la racine qui est correctement transactionnelle, mais ce n'est pas celui utilisé parce que le double de l'est "proche" de la servlet dans le parent/enfant, la hiérarchie, et le contexte, c'est de ne pas obtenir un <tx:annotation-driven/> configuration.

Quand j'ai changé la servlet context:component-scan tag à la place de point de au com.myapp.web et ensuite ajouté un context:component-scan tag de la data.xml fichier, tout a fonctionné.

Ça dépend encore un peu sur exactement quels fichiers de configuration vous étiez y compris en ce qui ApplicationContexts, mais au moins je peux dire que, ce faisant, vous avez retiré beaucoup de grains de la DispatcherServlet de contexte qui ont été à l'origine des problèmes. En particulier, votre correctement configuré @Transactional haricots dans le contexte de la racine n'aurait plus être occultée par des haricots dans le contexte enfant et serait injecté dans vos contrôleurs, de sorte que votre persistance choses devraient fonctionner ensuite.

Donc... la principale chose à retenir est que vous avez deux ApplicationContexts. Vous devez rester conscient de ce fait et de garder le contrôle de ce qui les haricots aller dans quel contexte.

Ne que tout couvrir?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X