1. Hintergrund
Kürzlich habe ich aufgrund von Problemen mit dem Paket-Scan des Projekts bei der Lösung des Problems versehentlich festgestellt, dass Spring und SpringMVC eine Eltern-Kind-Containerbeziehung haben, und genau deshalb tritt das Problem des Paketscannings häufig auf. Hier analysieren und verstehen wir die Beziehung zwischen Eltern und Kind zwischen Spring und SpringMVC und geben dem offiziellen empfohlenen Weg zum Scannen von Paket in Spring- und SpringMVC-Konfigurationsdateien.
2. Konzeptverständnis und Wissen legen die Grundlage
Im Kernkonzept des Gesamtrahmens von Spring sind Container die Kernidee, mit der der gesamte Lebenszyklus einer Bohne verwaltet wird. In einem Projekt gibt es nicht unbedingt nur einen Container. Die Feder kann mehrere Behälter umfassen und der Behälter verfügt über obere und untere Ebenen. Das derzeit häufigste Szenario besteht darin, die beiden Frameworks von Spring und SpringMVC in ein Projekt einzuführen. Dann sind es tatsächlich zwei Container. Frühling ist ein Elternbehälter und SpringMVC ist sein Kinderbehälter. Die im Spring Parent Container registrierten Bean ist im SpringMVC -Container sichtbar, während die im SpringMVC -Container registrierte Bean für den Spring Parent Container unsichtbar ist, dh der untergeordnete Container kann die registrierte Bohne im Elternbehälter sehen, sonst funktioniert er nicht.
Wir können die Unified Annotation -Konfiguration wie folgt verwenden, um die Bohnen zu registrieren, ohne jede Bean separat mithilfe von XML zu konfigurieren.
<Kontext: Komponenten-scan-Basis-Package = "com.Hafiz.www" />
Aus dem von Spring bereitgestellten Referenzhandbuch wissen wir, dass die Funktion dieser Konfiguration darin besteht, alle Klassen unter dem konfigurierten Basis-Package-Paket zu scannen, die die @Component-Annotation verwenden, und sie automatisch im Container registrieren. Gleichzeitig scannen sie auch die drei Anmerkungen von @Controller, @Service und @respository, weil sie von @Component geerbt werden.
Im Projekt sehen wir häufig die folgende Konfiguration. Tatsächlich kann dies mit der obigen Konfiguration weggelassen werden, da die obige Konfiguration die folgende Konfiguration standardmäßig aktiviert. Die folgende Konfiguration deklariert die Anmerkungen wie @Required, @Autowired, @Postconstruct, @Persistencontext, @Resource, @Predestroy usw. standardmäßig.
<Kontext: Annotation-Konfiguration/>
Zusätzlich gibt es eine weitere Konfiguration im Zusammenhang mit SpringMVC. Nach der Überprüfung muss dies für SpringMVC konfiguriert werden, da es @RequestMapping, @RequestBody, @ResponseBody usw. erklärt. Darüber hinaus lädt diese Konfiguration standardmäßig viele Parameterbindungsmethoden wie JSON -Conversion Parser.
<MVC: Annotationsgetrieben />
Die obige Satzkonfigurationsversion vor Spring 3.1 entspricht der folgenden Konfigurationsmethode
<!-Konfigurieren Sie Annotation Controller Mapper, es wird in SpringMVC verwendet, um die Anforderungsanforderungs-URL an einen bestimmten Controller zuzuordnen-> <bean/> <!-Konfigurieren Sie Annotation Controller Mapper. Sie wird in SpringMVC verwendet, um spezifische Anforderungen einer bestimmten Methode zuzuordnen-> <bean/>
Die Version nach Spring3.1 entspricht den folgenden Konfigurationsmethoden
<!-Konfigurieren Sie Annotation Controller Mapper, es wird in SpringMVC verwendet, um die Anforderungsanforderungs-URL an einen bestimmten Controller zuzuordnen-> <bean/> <!-Konfigurieren Sie Annotation Controller Mapper. Sie wird in SpringMVC verwendet, um spezifische Anforderungen einer bestimmten Methode zuzuordnen-> <bean/>
3.. Spezifische Szenarioanalyse
Schauen wir uns die Ursachen des Containerkonflikts zwischen Frühling und SpringMVC genauer an?
Wir haben zwei Container, Spring und SpringMVC, und ihre Konfigurationsdateien sind applicationContext.xml bzw. applicationContext-mvc.xml.
1. Der <Context: Komponenten-scan-Basis-Package = "com.Hafiz.www" /> ist in der applicationContext.xml konfiguriert, um für das Scannen und Registrieren aller Bohnen verantwortlich zu sein, die registriert werden müssen.
2. Konfigurieren <MVC: Annotationsgetrieben /> In ApplicationContext-mvc.xml verantwortlich für die Verwendung von SpringMVC-bezogenen Annotationen.
3. Als wir das Projekt starten, stellten wir fest, dass SpringMVC nicht springen konnte. Wir setzen die Protokolldruckpegel des Protokolls für das Debuggen für das Debuggen. Wir fanden heraus, dass die Anfragen im SpringMVC -Container dem spezifischen Controller nicht zugeordnet zu sein schienen.
4. Konfigurieren <Kontext: Komponent-scan base-package = "com.hafiz.www" /> in ApplicationContext-mvc.xml. Nach dem Neustart ist die Überprüfung erfolgreich und der SpringMVC -Sprung gültig.
Überprüfen Sie den spezifischen Grund, schauen Sie sich den Quellcode an und beginnen Sie von SpringMVCs DispatcherServlet, um nach unten zu suchen. Wir fanden heraus, dass wir beim Initialisierungs in SpringMVC nach allen Bohnen im SpringMVC -Behälter suchen, die die @Controller -Annotation verwenden, um festzustellen, ob es sich um einen Handler handelt. Durch die zweistufige Konfiguration von 1 und 2 wird der aktuelle SpringMVC-Container nicht mit der @Controller-Annotation registriert. Alle Beans mit der @Controller-Annotation sind jedoch im übergeordneten Frühlingscontainer registriert, sodass SpringMVC den Prozessor nicht finden kann und nicht springen kann. Der Kernquellcode lautet wie folgt:
Protected void initHandlermethods () {if (logger.isdebugenabled ()) {logger.debug ("Suchen nach Anforderungszuordnungen im Anwendungskontext:" + getApplicationContext ()); } String [] beannames = (thetEteTeTeThandLermethodsinancestorContexts? BeanfactoryUtils.BeannamesForTypeinCludedancestors (GetApplicationContext (), Object.class): GetApplicationContext (). für (string beanname: beannames) {if (isHandler (GetApplicationContext (). Gettype (Beanname))) {DetectHandLerMethods (Beanname); }} Handlermethodsinitialisierte (GetHandherethods ());}In der Methode IsHandler werden wir feststellen, ob die Annotation der Strombohne ein Controller ist. Der Quellcode lautet wie folgt:
Protected Boolean IsHandler (Klasse <?> BeanType) {return AnnotationUtils.findannotation (BeanType, Controller.Class)! = NULL;}In der 4. Schrittkonfiguration sind alle Bohnen mit @Controller -Annotation auch im SpringMVC -Container registriert, sodass SpringMVC den Prozessor zur Verarbeitung finden, sodass er normal springt.
Wir fanden den Grund, warum es nicht richtig springen kann. Was ist also seine Lösung?
Wir haben festgestellt, dass bei der Methode in der Inithandlermethods (), DetektumermethodsinancestorContexts Switch hauptsächlich steuert, welche Bohnen im Behälter erhalten werden und ob der übergeordnete Container enthalten ist. Es ist standardmäßig nicht enthalten. Die Lösung besteht also darin, die Eigenschaft von HandleMapping in der SpringMVC -Konfigurationsdatei zu true zu konfigurieren (hier müssen Sie feststellen, welcher Handlermapping nach dem spezifischen Projekt verwendet wird), damit die Bean des Elterncontainers erfasst werden kann. wie folgt:
<Bean> <Eigenschaft name = "DetectHandLermethodsinancestorContexts"> <wert> true </value> </property> </bean>
In den tatsächlichen Projekten wird es jedoch viele Konfigurationen geben. Wir teilen verschiedene Arten von Bohnen in verschiedenen Containern gemäß den offiziellen Empfehlungen nach verschiedenen Geschäftsmodulen: Der Spring Parent Container ist für die Registrierung aller anderen Bohnen verantwortlich, die von @Controller nicht kommentiert werden, während SpringMVC nur für die Registrierung von Bohnen von @Controller verantwortlich ist, sodass sie ihre eigenen Verantwortlichkeiten und Klärung von Begrenzungen klären. Die Konfigurationsmethode ist wie folgt
1.Configure in ApplicationContext.xml:
<!-Registrieren Sie Beans in Frühlingscontainern, die von @Controller nicht kommentiert werden-> <CONTEXT: COMPONENT-SCAN-BASE-PACKAGE = "COM.HAFIZ.WWW"> <context: schließen Sie Filter type = "Annotation" Expression = "org.springFramework.steretype.Controller"/> </> </> </> </contexte: component-scan> context: component-scan>
2. Konfiguration in applicationContext-mvc.xml
<!-Nur Bohnen mit @Controller-Annotation sind im SpringMVC-Container registriert-> <Kontext: Komponenten-scan-Basis-Package = "com.Hafiz.www" usedefault-filters = "false"> <context: include-filter type = "Annotation" Expression = "org.
3. Zusammenfassung
Auf diese Weise haben wir nach den offiziellen Vorschlägen die Beziehung zwischen Spring und SpringMVC und dem Prinzip des Scannens und Registrierungsprinzips und des Prinzips des Scannens und der Registrierung zugewiesen, nachdem wir verschiedene Arten von Bohnen für die Verwaltung unterschiedlicher Behälter zuordnen können. Wenn Probleme wie die Bean nicht gefunden werden können, kann SpringMVC nicht umgeleitet werden und die Transaktionskonfiguration fällt aus, wir können das Problem schnell lokalisieren und lösen. Sehr glücklich, gibt es irgendwelche ~
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.