Analyse des SpringBoot-Interceptor-Quellcodes
1. Was ist ein Interceptor (Interceptor) in Java? Er stellt einen Mechanismus bereit, der es Entwicklern ermöglicht, einen Code vor und nach der Ausführung einer Aktion auszuführen. Verhindert seine Ausführung vor der Ausführung und bietet außerdem eine Möglichkeit, wiederverwendbare Teile des Codes in der Aktion zu extrahieren. In AOP werden Interceptoren verwendet, um eine Methode oder ein Feld abzufangen, bevor darauf zugegriffen wird, und um dann bestimmte Operationen davor oder danach hinzuzufügen.
Die obige Aktion bezieht sich im Allgemeinen auf die Schnittstelle unserer Controller-Ebene.
2. Angepasster Interceptor
Im Allgemeinen ist das Anpassen eines Interceptors in drei Schritte unterteilt:
(1) Schreiben Sie einen Interceptor, um die HandlerInterceptor-Schnittstelle zu implementieren.
(2) Der Abfangjäger ist im Container registriert.
(3) Abfangregeln konfigurieren.
2.1 Einen Interceptor schreiben
Wir erstellen ein neues SpringBoot-Projekt und passen dann einen Interceptor LoginInterceptor an, um bestimmte Anfragen im nicht protokollierten Zustand abzufangen. Ab JDK 1.8 können Schnittstellenmethoden mit dem Standardschlüsselwort Standardimplementierungen haben. Um eine Schnittstelle zu implementieren, müssen Sie also nur die Methode ohne dieses Schlüsselwort implementieren.
import lombok.extern.slf4j.Slf4j; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 登录拦截器 */ @Slf4j public class LoginInterceptor implements HandlerInterceptor { /** * 目标方法执行之前执行 * @param request * @param response * @param handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 获取请求路径 String requestUrl = request.getRequestURI(); log.info("请求的路径是: {}", requestUrl); String username = request.getParameter("username"); if (username != null) { // 放行 return true; } request.setAttribute("msg", "请先登录"); // 携带msg跳转到登录页 request.getRequestDispatcher("/").forward(request, response); return false; } /** * 目标方法完成以后执行 * @param request * @param response * @param handler * @param modelAndView * @throws Exception */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.info("postHandle执行"); } /** * 页面渲染以后执行 * @param request * @param response * @param handler * @param ex * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { log.info("afterCompletion执行"); } }
2.2 Interceptoren registrieren und konfigurieren
Wenn wir in SpringBoot die Konfiguration anpassen müssen, müssen wir nur die WebMvcConfigurer-Klasse implementieren und die entsprechende Methode überschreiben. Hier müssen wir den Interceptor konfigurieren, also schreiben Sie einfach seine addInterceptors-Methode neu.
import com.codeliu.interceptor.LoginInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; // 表示这是一个配置类 @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/**") // 拦截所有路径 .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**"); // 不拦截这些路径 } }
Beachten Sie, dass wir bei der Konfiguration zum Abfangen aller Pfade statische Ressourcen ausschließen müssen, da sonst die Bildstile abgefangen werden.
Durch die oben genannten Schritte haben wir einen dem System hinzugefügten Abfangjäger implementiert. Beginnen Sie einfach mit der Verifizierung.
3. Interceptor-Prinzip
Wir verwenden die Breakpoint-Debugging-Methode, um zu sehen, wie die Browseranforderung vom Anfang bis zum Backend verarbeitet wird. Fügen Sie einen Haltepunkt in die doDispatch-Methode von DispatcherServlet ein. Dies ist der Einstiegspunkt der Anfrage. Nachdem der Browser die Anfrage gesendet hat, wird sie von dieser Methode weitergeleitet und verarbeitet.
Starten Sie die Anwendung im Debug-Modus, greifen Sie auf eine beliebige Schnittstelle zu und verfolgen Sie den Codeprozess
3.1 Finden Sie den Handler, der die Anfrage verarbeiten kann, und alle Abfangjäger des Handlers
Hier haben wir den HandlerExecutionChain und gefunden die Interceptor-Kette, die aus drei Interceptoren besteht: Interceptor, unserem benutzerdefinierten
LoginInterceptor
3.2 Führen Sie die preHandle-Methode des Interceptors aus.
In der doDispatch-Methode gibt es die folgenden zwei Codezeilen.
// 执行拦截器的preHandle方法,如果返回为fasle,则直接return,不执行目标方法 if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // 反射执行目标方法 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
Wir geben die applyPreHandle-Methode ein, um die Logik der Methode anzuzeigen Wenn der aktuelle Interceptor Wenn die preHandle-Methode true zurückgibt, wird die preHandle-Methode des nächsten Interceptors weiterhin ausgeführt, andernfalls wird die afterCompletion-Methode des Interceptors ausgeführt.
Dann schauen wir uns die Logik der Methode triggerAfterCompletion an.
/** * Apply preHandle methods of registered interceptors. * @return {@code true} if the execution chain should proceed with the * next interceptor or the handler itself. Else, DispatcherServlet assumes * that this interceptor has already dealt with the response itself. */ boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { // 遍历拦截器 for (int i = 0; i < this.interceptorList.size(); i++) { HandlerInterceptor interceptor = this.interceptorList.get(i); // 执行当前拦截器的preHandle方法 if (!interceptor.preHandle(request, response, this.handler)) { // 如果preHandle方法返回为false,则执行当前拦截器的afterCompletion方法 triggerAfterCompletion(request, response, null); return false; } // 记录当前拦截器的下标 this.interceptorIndex = i; } return true; }
Durch den obigen Code wissen wir, dass die afterCompletion-Methode des Interceptors umgekehrt ausgeführt wird.
3.3 Führen Sie die Zielmethode aus
Wenn alle PreHandle-Methoden des oben genannten Interceptors true zurückgeben, gibt es in der doDispatch-Methode keine direkte Rückgabe, aber die Zielmethode wird weiterhin ausgeführt. Wenn die preHandle-Methode eines Interceptors false zurückgibt, kehrt die doDispatch-Methode nach der Ausführung der afterCompletion-Methode des Interceptors (des Interceptors, der die preHandle-Methode ausgeführt hat) direkt zurück und die Zielmethode wird nicht ausgeführt.
Führen Sie die Zielmethode über den folgenden Code aus
/** * Trigger afterCompletion callbacks on the mapped HandlerInterceptors. * Will just invoke afterCompletion for all interceptors whose preHandle invocation * has successfully completed and returned true. */ void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) { // 反向遍历拦截器 for (int i = this.interceptorIndex; i >= 0; i--) { HandlerInterceptor interceptor = this.interceptorList.get(i); try { // 执行当前拦截器的afterCompletion方法 interceptor.afterCompletion(request, response, this.handler, ex); } catch (Throwable ex2) { logger.error("HandlerInterceptor.afterCompletion threw exception", ex2); } } }
Ich werde nicht auf die spezifische interne Ausführung achten, sondern auf die Logik nach der Ausführung.
3.4 Führen Sie die postHandle-Methode des Interceptors aus.
Nachdem die Zielmethode ausgeführt wurde, geht der Code aus.
// Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
Sehen Sie sich die Logik von applyPostHandle an Methode des Abfangjägers
Weiter Gehen Sie nach unten
mappedHandler.applyPostHandle(processedRequest, response, mv);
und geben Sie diese Methode ein. Diese Methode verarbeitet die Ausführungsergebnisse und rendert die Seite. Führen Sie am Ende dieser Methode den folgenden Code aus
3.6 Ausnahmebehandlung Wenn während der Ausführung der doDispatch-Methode eine Ausnahme ausgelöst wird, lösen Ausnahmen im Catch-Modul die Ausführung der afterCompletion-Methode ausDas obige ist der detaillierte Inhalt vonAnalyse des SpringBoot-Interceptor-Quellcodes. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Einführung in Jasypt Jasypt ist eine Java-Bibliothek, die es einem Entwickler ermöglicht, seinem Projekt mit minimalem Aufwand grundlegende Verschlüsselungsfunktionen hinzuzufügen und kein tiefes Verständnis der Funktionsweise der Verschlüsselung erfordert. standardbasierte Verschlüsselungstechnologie. Passwörter, Text, Zahlen, Binärdateien verschlüsseln ... Geeignet für die Integration in Spring-basierte Anwendungen, offene API, zur Verwendung mit jedem JCE-Anbieter ... Fügen Sie die folgende Abhängigkeit hinzu: com.github.ulisesbocchiojasypt-spring-boot-starter2 Die Vorteile von Jasypt schützen unsere Systemsicherheit. Selbst wenn der Code durchgesickert ist, kann die Datenquelle garantiert werden.

Nutzungsszenario 1. Die Bestellung wurde erfolgreich aufgegeben, die Zahlung erfolgte jedoch nicht innerhalb von 30 Minuten. Die Zahlung ist abgelaufen und die Bestellung wurde automatisch storniert. 2. Die Bestellung wurde unterzeichnet und es wurde 7 Tage lang keine Bewertung durchgeführt. Wenn die Bestellung abläuft und nicht ausgewertet wird, wird die Bestellung standardmäßig positiv bewertet. Wenn der Händler die Bestellung innerhalb von 5 Minuten nicht erhält, wird die Bestellung abgebrochen Es wird eine SMS-Erinnerung gesendet ... Für Szenarien mit langen Verzögerungen und geringer Echtzeitleistung können wir die Aufgabenplanung verwenden, um eine regelmäßige Abfrageverarbeitung durchzuführen. Zum Beispiel: xxl-job Heute werden wir auswählen

1. Redis implementiert das Prinzip der verteilten Sperren und warum verteilte Sperren erforderlich sind. Bevor über verteilte Sperren gesprochen wird, muss erläutert werden, warum verteilte Sperren erforderlich sind. Das Gegenteil von verteilten Sperren sind eigenständige Sperren. Wenn wir Multithread-Programme schreiben, vermeiden wir Datenprobleme, die durch den gleichzeitigen Betrieb einer gemeinsam genutzten Variablen verursacht werden. Normalerweise verwenden wir eine Sperre, um die Richtigkeit der gemeinsam genutzten Variablen sicherzustellen Die gemeinsam genutzten Variablen liegen im gleichen Prozess. Wenn es mehrere Prozesse gibt, die gleichzeitig eine gemeinsam genutzte Ressource betreiben müssen, wie können sie sich dann gegenseitig ausschließen? Heutige Geschäftsanwendungen sind in der Regel Microservice-Architekturen, was auch bedeutet, dass eine Anwendung mehrere Prozesse bereitstellen muss. Wenn mehrere Prozesse dieselbe Datensatzzeile in MySQL ändern müssen, ist eine Verteilung erforderlich, um fehlerhafte Daten zu vermeiden wird zu diesem Zeitpunkt eingeführt. Der Stil ist gesperrt. Punkte erreichen wollen

Springboot liest die Datei, kann aber nach dem Packen in ein JAR-Paket nicht auf die neueste Entwicklung zugreifen. Es gibt eine Situation, in der Springboot die Datei nach dem Packen in ein JAR-Paket nicht lesen kann ist ungültig und kann nur über den Stream gelesen werden. Die Datei befindet sich unter resources publicvoidtest(){Listnames=newArrayList();InputStreamReaderread=null;try{ClassPathResourceresource=newClassPathResource("name.txt");Input

Wenn Springboot + Mybatis-plus keine SQL-Anweisungen zum Hinzufügen mehrerer Tabellen verwendet, werden die Probleme, auf die ich gestoßen bin, durch die Simulation des Denkens in der Testumgebung zerlegt: Erstellen Sie ein BrandDTO-Objekt mit Parametern, um die Übergabe von Parametern an den Hintergrund zu simulieren dass es äußerst schwierig ist, Multi-Table-Operationen in Mybatis-plus durchzuführen. Wenn Sie keine Tools wie Mybatis-plus-join verwenden, können Sie nur die entsprechende Mapper.xml-Datei konfigurieren und die stinkende und lange ResultMap konfigurieren Schreiben Sie die entsprechende SQL-Anweisung. Obwohl diese Methode umständlich erscheint, ist sie äußerst flexibel und ermöglicht es uns

SpringBoot und SpringMVC sind beide häufig verwendete Frameworks in der Java-Entwicklung, es gibt jedoch einige offensichtliche Unterschiede zwischen ihnen. In diesem Artikel werden die Funktionen und Verwendungsmöglichkeiten dieser beiden Frameworks untersucht und ihre Unterschiede verglichen. Lassen Sie uns zunächst etwas über SpringBoot lernen. SpringBoot wurde vom Pivotal-Team entwickelt, um die Erstellung und Bereitstellung von Anwendungen auf Basis des Spring-Frameworks zu vereinfachen. Es bietet eine schnelle und einfache Möglichkeit, eigenständige, ausführbare Dateien zu erstellen

1. Passen Sie den RedisTemplate1.1-Standard-Serialisierungsmechanismus an. Die API-basierte Redis-Cache-Implementierung verwendet die RedisTemplate-Vorlage für Daten-Caching-Vorgänge. Öffnen Sie hier die RedisTemplate-Klasse und zeigen Sie die Quellcodeinformationen der Klasse publicclassRedisTemplateextendsRedisAccessorimplementsRedisOperations an. Schlüssel deklarieren, verschiedene Serialisierungsmethoden des Werts, der Anfangswert ist leer @NullableprivateRedisSe

In Projekten werden häufig einige Konfigurationsinformationen benötigt. Diese Informationen können in der Testumgebung und in der Produktionsumgebung unterschiedliche Konfigurationen haben und müssen möglicherweise später basierend auf den tatsächlichen Geschäftsbedingungen geändert werden. Wir können diese Konfigurationen nicht fest im Code codieren. Am besten schreiben Sie sie in die Konfigurationsdatei. Sie können diese Informationen beispielsweise in die Datei application.yml schreiben. Wie erhält oder verwendet man diese Adresse im Code? Es gibt 2 Methoden. Methode 1: Wir können den Wert, der dem Schlüssel in der Konfigurationsdatei (application.yml) entspricht, über den mit @Value versehenen Wert erhalten. Diese Methode eignet sich für Situationen, in denen es relativ wenige Mikrodienste gibt: Tatsächlich Projekte, wenn das Geschäft kompliziert ist, Logik
