1. Contexte
Récemment, en raison de problèmes avec la numérisation du package du projet, en train de résoudre le problème, j'ai découvert accidentellement que Spring et SpringMVC ont une relation de conteneur parent-enfant, et c'est précisément à cause de cela que le problème de la numérisation des paquets se produit souvent. Ici, nous analysons et comprenons la relation de conteneur parent-enfant entre Spring et SpringMVC et donnons le mode de numérisation officiel recommandé dans les fichiers de configuration Spring et SpringMVC.
2. Compréhension du concept et connaissances jetant les bases
Dans le concept principal du cadre global de Spring, les conteneurs sont l'idée principale, qui est utilisée pour gérer l'ensemble du cycle de vie d'un haricot. Dans un projet, il n'y a pas nécessairement un seul conteneur. Le ressort peut inclure plusieurs conteneurs et le conteneur a des niveaux supérieurs et inférieurs. Le scénario le plus courant est actuellement d'introduire les deux cadres de Spring et SpringMVC dans un projet. Alors ce sont en fait deux conteneurs. Le printemps est un conteneur parent et SpringMVC est son conteneur enfant. Le haricot enregistré dans le conteneur parent de Spring est visible dans le conteneur SpringMVC, tandis que le bean enregistré dans le conteneur SpringMVC est invisible pour le conteneur parent de Spring, c'est-à-dire que le conteneur enfant peut voir le bean enregistré dans le conteneur parent, sinon il ne fonctionnera pas.
Nous pouvons utiliser la configuration d'annotation unifiée comme suit pour enregistrer par lots les haricots, sans configurer chaque bean à l'aide de XML séparément.
<Context: Component-Scan Base-Package = "com.hafiz.www" />
Dans le manuel de référence fourni par Spring, nous savons que la fonction de cette configuration est de numériser toutes les classes dans le package de basage de base configuré qui utilise l'annotation @component et de les enregistrer automatiquement dans le conteneur. Dans le même temps, ils scannent également les trois annotations de @Controller, @Service et @SposOsository car ils sont hérités de @Component.
Dans le projet, nous voyons souvent la configuration suivante. En fait, avec la configuration ci-dessus, cela peut être omis, car la configuration ci-dessus allumera la configuration suivante par défaut. La configuration suivante déclarera les annotations telles que @Required, @Autowired, @PostConstruct, @PerSisTenConText, @Resource, @Predestroy, etc. par défaut.
<Context: Annotation-Config />
De plus, il existe une autre configuration liée à SpringMVC. Après vérification, cela doit être configuré pour SpringMVC car il déclare @RequestMapping, @Requestbody, @ResponseBody, etc.
<MVC: annotation-axé />
La version de configuration de la phrase ci-dessus avant Spring 3.1 est équivalente à la méthode de configuration suivante
<! - Configurer le mappeur du contrôleur d'annotation, il est utilisé dans SpringMVC pour mapper l'URL de demande de demande à un contrôleur spécifique -> <Bean /> <! - Configurez le mappeur du contrôleur d'annotation, il est utilisé dans SpringMVC pour cartographier des demandes spécifiques à une méthode spécifique -> <Ean />
La version après Spring3.1 est équivalente aux méthodes de configuration suivantes
<! - Configurer le mappeur du contrôleur d'annotation, il est utilisé dans SpringMVC pour mapper l'URL de demande de demande à un contrôleur spécifique -> <Bean /> <! - Configurez le mappeur du contrôleur d'annotation, il est utilisé dans SpringMVC pour cartographier des demandes spécifiques à une méthode spécifique -> <Ean />
3. Analyse de scénario spécifique
Examinons de plus près les causes du conflit de conteneurs entre le printemps et le printemps?
Nous avons deux conteneurs, Spring et Springmvc, et leurs fichiers de configuration sont respectivement applicables Context.xml et applicationContext-mvc.xml.
1. Le <Context: Component-Scan Base-Package = "com.hafiz.www" /> est configuré dans l'applicationContext.xml pour être responsable de la numérisation et de l'enregistrement de tous les beans qui doivent être enregistrés.
2. Configurez <MVC: Annotation-Driven /> dans ApplicationContext-Mvc.xml pour être responsable de l'utilisation des annotations liées à SpringMVC.
3. Lors du démarrage du projet, nous avons constaté que SpringMVC ne pouvait pas sauter. Nous définissons le niveau d'impression du journal du journal pour déboguer pour le débogage. Nous avons constaté que les demandes dans le conteneur SpringMVC ne semblaient pas être mappées sur le contrôleur spécifique.
4. Configure <contexte: composant-scan basage-package = "com.hafiz.www" /> dans applicationContext-mvc.xml. Après le redémarrage, la vérification est réussie et le saut SpringMVC est valide.
Vérifions la raison spécifique, examinons le code source et commençons à partir de DispatcherServlet de Springmvc pour rechercher. Nous avons constaté que lorsque SpringMVC est initialisé, nous rechercherons tous les haricots du conteneur SpringMVC qui utilisent l'annotation @Controller pour déterminer s'il s'agit d'un gestionnaire. La configuration en deux étapes de 1 et 2 fait que le conteneur SpringMVC actuel n'enregistre pas le bean avec l'annotation @Controller, mais tous les beans avec l'annotation @Controller sont enregistrés dans le conteneur parent de Spring, donc SpringMVC ne peut pas trouver le processeur et ne peut pas sauter. Le code source de base est le suivant:
Protected void IniThandLerMethods () {if (logger.isdebugeNable ()) {logger.debug ("à la recherche de mappages de demande dans le contexte de l'application:" + GetApplicationContext ()); } String [] beanNames = (this.detecthandLerMethodSinancestorContexts? Beanfactoryutils.beanNamesFortyTyPyCludeDanceStors (getApplicationContext (), object.class): getApplicationContext (). GetBeanNamesForty (object.class)); for (string beanname: beanNames) {if (isHandler (getApplicationContext (). getType (beanname))) {DeteteCthandLerMethods (beanname); }} handlerMethodsinitialized (GethandlerMethods ());}Dans la méthode ISHandler, nous déterminerons si l'annotation du haricot actuel est un contrôleur. Le code source est le suivant:
Boolean ISHandler protégé (classe <?> beanType) {return annotationutils.findannotation (beanType, contrôleur.class)! = null;}Dans la configuration de la 4e étape, tous les haricots avec annotation @Controller sont également enregistrés dans le conteneur SpringMVC, de sorte que SpringMVC peut trouver le processeur de traitement, donc il saute normalement.
Nous avons trouvé la raison pour laquelle il ne peut pas sauter correctement, alors quelle est sa solution?
Nous avons remarqué que dans la méthode InithandLerMethods (), le commutateur de détection des aléméméthodies, il contrôle principalement les haricots dans le récipient et si le conteneur parent est inclus. Il n'est pas inclus par défaut. La solution consiste donc à configurer la propriété DeteteCthandLerMethodsInancestorContexts de Handlermapping to true dans le fichier de configuration de SpringMVC (ici, vous devez voir quel type de handlermapping est utilisé en fonction du projet spécifique), afin qu'il puisse détecter le bean du conteneur parent. comme suit:
<an bean> <propriété name = "DeteteCthandLerMethodSinancestorContexts"> <value> true </value> </promidér> </ank>
Cependant, dans les projets réels, il y aura de nombreuses configurations. Nous divisons différents types de haricots dans différents conteneurs en fonction des recommandations officielles en fonction de différents modules commerciaux: le conteneur parent de Spring est responsable de l'enregistrement de tous les autres haricots qui ne sont pas annotés par @Controller, tandis que SpringMVC n'est responsable que de l'enregistrement des beans annotés par @Controller, de sorte qu'ils assument chacun leurs propres responsabilités et clarifient les limites. La méthode de configuration est la suivante
1.Configure dans ApplicationContext.xml:
<! - Enregistrez les haricots dans des conteneurs à ressort qui ne sont pas annotés par @Controller -> <context: Component-Scan Base-Package = "com.hafiz.www"> <context: exclude-filter type = "annotation" expression = "org.springframework.steretype.contreller" /> </ context: component-scan>
2.Configuration dans ApplicationContext-Mvc.xml
<! - Seuls les haricots avec annotation @Controller sont enregistrés dans le conteneur SpringMvc -> <Context: Component-Scan Base-Package = "com.hafiz.www" Use-Default-Filters = "false"> <context: include-filter type = "annotation" expression = "org.springframework.stereType.Controller"
3. Résumé
De cette façon, après avoir compris la relation de conteneurs parent-enfant entre le printemps et le printemps et le principe de numérisation et d'enregistrement, selon les suggestions officielles, nous pouvons allouer différents types de haricots à différents conteneurs pour la gestion. S'il y a des problèmes tels que le bean ne peut être trouvé, SpringMVC ne peut pas être redirigé et la configuration de la transaction échoue, nous pouvons rapidement localiser et résoudre le problème. Très heureux, y a-t-il un ~
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.