Der Front-End-Controller ist der zentralste Teil des gesamten MVC-Frameworks. Es wird hauptsächlich verwendet, um externe Anforderungen abzufangen, die den Anforderungen entsprechen und die Anforderungen an verschiedene Controller zur Verarbeitung verteilen. Gemäß den Ergebnissen der Verarbeitung des Controllers generiert es entsprechende Antworten und sendet sie an den Client. Der Front-End-Controller kann mit dem Filter (Struts2 verwendet diese Methode) oder des Servlet (Feder MVC Framework) implementiert werden.
Als Vorkontroller ist der DispatcherServlet der Eingang zum Webserver und die wichtigste Klasse von Spring MVC. Durch seinen Lebenszyklus kann das Verständnis des Webservers vertieft werden.
Lebenszyklus von Servlet
Erinnern wir uns zunächst an den Lebenszyklus des Servlets:
Der Dienerlebenszyklus ist in drei Phasen unterteilt: [detaillierte Erklärung des Dienerlebenszyklus und des Arbeitsprinzips]
1. Init () Methode heißt init () in der Initialisierungsphase. Nach dem Laden des Servlets erstellt der Servlet -Container eine Servlet -Instanz und ruft die Init () -Methode des Servlets für die Initialisierung auf. Die Init () -Methode wird nur einmal während des gesamten Lebens eines Servlets bezeichnet.
2. Rufen Sie die Methode service () als Antwort auf die Client -Anforderungsstufe an
3. CALL DESTREL () -Methode in der Terminationsphase
Servlet -Initialisierungsphase
In den folgenden Momenten lädt der Servlet Container das Servlet:
1. Wenn der Servlet -Behälter beginnt, werden einige Servlets automatisch geladen. Um es zu implementieren, müssen Sie nur den folgenden Code zwischen <servlet> </servlet> in der Datei web.xml hinzufügen:
<Loadon-Startups> 1 </loadon-startup>
2. Nachdem der Servlet -Container gestartet wurde, sendet der Kunde zum ersten Mal eine Anfrage an den Servlet
3. Nachdem die Servlet -Klassendatei aktualisiert wurde, laden Sie das Servlet neu laden
Die Struktur des DispatcherServlets
Schauen wir uns nach der Überprüfung des obigen Wissens die Struktur des Dispatcherservlet an:
Dispatherservlet ererbt aus abstrakter Klasse: FrameworkServlet, indirekt HttpServlet (FrameworkServlet erbt sich von httpServletbean und HttpServletbean erbt von httpServlet)
Servlet -Initialisierung
Protected void InitStrategies (ApplicationContext -Kontext) {initmultipArtresolver (Kontext); // Datei hochladen und analysieren. Wenn der Anforderungsart mehrfach ist, laden Sie das Datei hoch und analysieren Sie sie über Multipartresolver. initlocaleresolver (Kontext); // Lokalisierung analysieren initthemeresolver (Kontext); // Themen anhändigen initHandlermappings (Kontext); // Zuordnungsanforderungen an den Prozessor inhandlerAdapters (Kontext); // Kartierung mehrerer Arten von Prozessoren in der THANDRERExceptionResolvers (Kontext); // Unterstützung mehrerer Arten von Prozessoren durch Handleradapter; // Wenn eine Ausnahme während der Ausführung auftritt, wird sie an HandleExceptionResolver übergeben, um initrequesttoviewnametranslator (Kontext) analysiert zu werden. // die Anforderung direkt an den Ansichtsnamen initviewResolvers (Kontext) analysieren; // den Namen des logischen Ansichts auf die spezifische Ansicht über ViewResolver auflösen, um initflashMapmanager (Kontext) zu implementieren. // Flash Map Manager}So behandeln Sie Anfragen:
Die Servicemethode des Servlet behandelt HTTP -Anforderungen.
FrameworkServlet.java definiert den Dienst und zerstören Sie die Methoden von Servlet, wie unten gezeigt:
/** * Überschreiben Sie die Implementierung der übergeordneten Klassen, um Patch -Anfragen abzufangen. */ @Override Protected void Service (httpServletRequest -Anforderung, httpServletResponse -Antwort) löst ServletException aus, iOException {String method = request.getMethod (); if (method.equalSignoreCase (requestMethod.patch.name ())) {processRequest (request, Antwort); } else {Super.Service (Anfrage, Antwort); }}Wir wissen, dass es sieben Arten von HTTP -Anforderungstypen gibt (plus Option), die wie folgt definiert sind:
public enum requestMethod {get, head, post, put, patch, löschen, Optionen, Trace} Der Service () des FrameworkServlet wird unterschiedliche Anfragen behandelt. Wir verwenden gemeinsame Beiträge, um zu veranschaulichen:
/*** Verarbeiten Sie diese Anfrage und veröffentlichen Sie ein Ereignis unabhängig vom Ergebnis. * <P> Die tatsächliche Ereignisbehandlung wird von der Zusammenfassung * {@link #doService} Vorlagenmethode durchgeführt. */ Protected Final Void ProcessRequest (httpServletRequest -Anforderung, HttpServletResponse -Antwort) löst ServletException aus, IoException {Long start time = system.currentTimemillis (); Throwable failureCause = null; LocaleContext potherLocalContext = localContextHolder.getLocalContext (); LocalContext localeContext = BuildLocalContext (Anfrage); RequestAttributes PriorAttributes = RequestContexTHOLDER.GetRequestAttributes (); ServletRequestAttributes RequestAttributes = BuildRequestAttributes (Anfrage, Antwort, vorherige Attributes); WebasyncManager asyncManager = webasyncutils.getAsyncManager (Anfrage); AsyncManager.registerCallableInterceptor (FrameworkServlet.class.getName (), New RequestBindingInterceptor ()); InitcontexTHOLDERS (Anfrage, localContext, RequestAttributes); Versuchen Sie {doService (Anfrage, Antwort); } catch (ServletException ex) {failureCause = ex; Ex werfen; } catch (ioException ex) {failureCause = ex; Ex werfen; } catch (throwable ex) {failureCause = ex; neue nestedServletException werfen ("Anfrageverarbeitung fehlgeschlagen", Ex); } endlich {ResetContextHolders (Request, voreinentwickeltesContext, vorherige Attributes); if (RequestAttributes! } if (logger.isdebugenabled ()) {if (failurecause! } else {if (asyncManager.isconcurrentHandlingstarted ()) {logger.debug ("Reaktion für die gleichzeitige Verarbeitung offen"); } else {this.logger.debug ("erfolgreich abgeschlossene Anfrage"); }}} PublishRequestHandledeDeVent (Anfrage, StartTime, failureCause); }} Das FrameworkServlet definiert abstrakt den Verarbeitungsfluss und überlässt ihn unter Klassen, um die Methode zu implementieren, und vervollständigt die spezifische Anforderungsverarbeitung.
/** * Unterklassen müssen diese Methode implementieren, um die Arbeit des Anfrage zu behandeln. * <p> Der Vertrag ist im Wesentlichen der gleiche wie der für die allgemein überschriebene * {@code doget} oder {@code dopost} Methoden von httpServlet. . * @param Anfrage aktuelle HTTP -Anforderung * @param Antwortstrom HTTP -Antwort * @throws Ausnahme im Falle eines Verarbeitungsfehlers * @see javax.servlet.http.httpServlet#dagget * @see javax.servlet.http.htttplet#Dopost#dopost HttpServletResponse -Antwort) löst eine Ausnahme aus;Die spezifische Implementierung ist wie folgt:
/** * Enthält die Dispatherservlet-spezifischen Anforderungsattribute und Delegierten an {@link #Dodispatch} * für die tatsächliche Versand. */ @Override Protected void doService (httpServletRequest -Anforderung, httpServletResponse -Antwort) löst eine Ausnahme aus {if (logger.isdebugenabled ()) {String resulted = webasyncutils.getAsyncManager (Anfrage) .hasconcurrentresult ()? "wieder aufgenommen": ""; logger.debug ("DispatcherServlet mit Name '" + getServletName () + "'" + wieder aufgenommen + "Verarbeitung" + request.getMethod () + "Anfrage für [" + getRequesturi (Anfrage) + "]"); } // Halten Sie einen Schnappschuss der Anforderungsattribute im Falle eines Include, //, um die ursprünglichen Attribute nach dem Einfügen wiederherzustellen. Karte <String, Object> AttributessNapshot = NULL; if (webutils.issincluderequest (request)) {attributessnapshot = new HashMap <String, Object> (); Enumeration <?> Attrnames = request.getAttributenames (); while (attrnames.hasmoreElements ()) {String attrName = (String) attrnames.nextElement (); if (this.cleanUpAfterClude || attrName.startswith ("org.springframework.web.servlet") {AttributessNapshot.put (attrName, request.getAttribute (attrName)); }}}} // Machen Sie Handlern und Objekten an. request.setAttribute (web_application_context_attribute, getWebApplicationContext ()); request.setAttribute (localAmale_resolver_attribute, this.localeresolver); request.setAttribute (themen_resolver_attribute, themeresolver); Request.SetAttribute (themen_source_attribute, GetTHemesource ()); FlashMap inputFlashMap = this.flashMapManager.ReTrieveandUpDate (Request, Antwort); if (inputFlashMap! = null) {request.setAttribute (input_flash_map_attribute, collections.unmodifiablemap (inputFlashMap)); } request.setAttribute (output_flash_map_attribute, new flashMap ()); Request.SetAtTribute (flash_map_manager_attribute, this.flashMapManager); Versuchen Sie {dodispatch (Anfrage, Antwort); } endlich {if (WebAsyncutils.getAsyncManager (Anfrage) .isconcurrentHandlingStarted ()) {return; } // Im Include -Fall den ursprünglichen Attribut -Snapshot wiederherstellen. if (Attributessnapshot! }}}Das Highlight als Implementierung des Anforderungsverteilers:
Funktionen: 1. Verteilen Sie die Anforderung an den Handler (erhalten Sie die Servlet Mapping -Beziehung in der Reihenfolge der Konfiguration); 2. Fragen Sie den ersten Handler ab, der auf der Grundlage der vom Servlet installierten Handleradapter verarbeitet werden kann. 3. Die Handler löst die Bearbeitung der Anfrage aus
/*** Verarbeiten Sie die tatsächliche Versendung in den Handler. * <P> Der Handler wird durch die Anwendung der Handlermappings des Servlets in Ordnung erhalten. * Der Handleradapter wird erhalten, indem die installierten Handleradapter des Servlets abfragt *, um den ersten zu finden, der die Handlerklasse unterstützt. * <p> Alle HTTP -Methoden werden mit dieser Methode behandelt. Es liegt an Handleradaptern oder Handlern * selbst zu entscheiden, welche Methoden akzeptabel sind. * @Param Anfrage aktuelle HTTP -Anforderung * @param Antwortstrom HTTP -Antwort * @throws -Ausnahme im Falle einer Art von Verarbeitungsfehler */ Protected void dodispatch (httpServletRequest -Anforderung, httpServletResponse) Ausnahme von {httpletRequest processedRequest = Anforderung; HandlexexexexexcutionChain MappedHandler = NULL; boolean multipArtrequestParsed = false; WebasyncManager asyncManager = webasyncutils.getAsyncManager (Anfrage); try {modelAndView mv = null; AUCECT SISSATCHEDEXCTION = NULL; try {processedRequest = checkMultiPart (Anfrage); multipArtrequestParsed = (ProcessedRequest! = Anfrage); // Handler für die aktuelle Anfrage bestimmen. MappedHandler = GetHandler (ProcessedRequest); if (mappedHandler == null || mappedHandler.getHandler () == null) {noHandlerFound (processedRequest, Antwort); zurückkehren; } // Handleradapter für die aktuelle Anforderung bestimmen. Handleradapter HA = GetHandlerAdapter (MappedHandler.GetHandler ()); // Last-modifizierter Header verarbeiten, falls vom Handler unterstützt wird. String method = request.getMethod (); boolean isget = "get" .equals (Methode); if (isget || "head" .equals (methode)) {long lastModified = ha.getLastModified (request, mappedHandler.getHandler ()); if (logger.isdebugenabled ()) {logger.debug ("Letztermodifizierter Wert für [" + getRequesturi (Anfrage) + "] ist:" + lastModified); } if (new ServletWebRequest (Anfrage, Antwort) .ChecknotModified (lastModified) && isget) {return; }} if (new ServletWebRequest (Anfrage, Antwort) .ChecknotModified (lastModified) && isget) {return; }} if (! mappedHandler.applyprehandle (processedRequest, Antwort)) {return; } try {// berufst tatsächlich den Handler. mv = ha.handle (processedRequest, reaktion, mappedHandler.getHandler ()); } endlich {if (asyncManager.isconcurrentHandlingstarted ()) {return; }} applyDefaultViewName (Request, MV); MappedHandler.Applyposthandle (ProcessedRequest, Response, MV); } catch (Ausnahme ex) {SISPATCHException = Ex; } processDispatchResult (ProcessedRequest, Reaktion, MappedHandler, MV, SendatchException); } catch (Ausnahme ex) {TriggerAfterCompletion (ProcessedRequest, Antwort, MappedHandler, Ex); } catch (error err) {TriggerAfterCompletionWitherRor (ProcessedRequest, Antwort, MappedHandler, Err); } endlich {if (asyncManager.isconcurrentHandlingStarted ()) {// anstelle von Posthandle und AfterCompletion MappedHandler.ApplyAfterConcurrentHandlingStarted (processedRequest, Antwort); zurückkehren; } // Entfernen Sie alle Ressourcen, die von einer mehrteiligen Anforderung verwendet werden. if (multipArtrequestParsed) {CleanUpMultipart (processedRequest); }}}Servlet Zerstörung
/*** Schließen Sie den WebApplicationContext dieses Servlets. * @see org.springframework.context.configurableApplicationContext#close () */ @Override public void destroy () {getServletContext (). log ("zerstören Spring FrameworkServlet '" + GetServletName () + ""); // Nur close () auf WebApplicationContext aufrufen, wenn lokal verwaltet ... if (this.webApplicationContext InstanceOf configurableApplicationContext &&! This.webApplicationContextinjected) {((configurableApplicationContext) this.webApplicationContextContext) .CLOSE (). }}Zusammenfassung:
Aufgrund der Einschränkungen des Kapitels führt dieser Artikel nur den Anforderungsverarbeitungsprozess ein und führt keine eingehende Analyse des Codes durch. Der nächste Artikel beginnt mit den Details und analysiert die Schönheit des Frühlingscode.
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.