Inhaltsverzeichnis
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.
Im Allgemeinen ist das Anpassen eines Interceptors in drei Schritte unterteilt:
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.
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.
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.
In der doDispatch-Methode gibt es die folgenden zwei Codezeilen.
Führen Sie die Zielmethode über den folgenden Code aus
Sehen Sie sich die Logik von applyPostHandle an Methode des Abfangjägers
Heim Java javaLernprogramm Analyse des SpringBoot-Interceptor-Quellcodes

Analyse des SpringBoot-Interceptor-Quellcodes

May 15, 2023 pm 12:28 PM
springboot

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执行");
    }
}
Nach dem Login kopieren

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/**");  // 不拦截这些路径
    }
}
Nach dem Login kopieren

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.

Analyse des SpringBoot-Interceptor-QuellcodesStarten 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

Analyse des SpringBoot-Interceptor-QuellcodesHier haben wir den HandlerExecutionChain und gefunden die Interceptor-Kette, die aus drei Interceptoren besteht: Interceptor, unserem benutzerdefinierten

und den standardmäßigen zwei Interceptoren des Systems.

LoginInterceptor3.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());
Nach dem Login kopieren

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;
}
Nach dem Login kopieren

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);
        }
    }
}
Nach dem Login kopieren

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());
Nach dem Login kopieren
.

Sehen Sie sich die Logik von applyPostHandle an Methode des Abfangjägers

Weiter Gehen Sie nach unten

mappedHandler.applyPostHandle(processedRequest, response, mv);
Nach dem Login kopieren

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 aus

Analyse des SpringBoot-Interceptor-Quellcodes

Das 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!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat -Befehle und wie man sie benutzt
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Wie Springboot Jasypt integriert, um die Verschlüsselung von Konfigurationsdateien zu implementieren Wie Springboot Jasypt integriert, um die Verschlüsselung von Konfigurationsdateien zu implementieren Jun 01, 2023 am 08:55 AM

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.

Wie SpringBoot Redisson integriert, um eine Verzögerungswarteschlange zu implementieren Wie SpringBoot Redisson integriert, um eine Verzögerungswarteschlange zu implementieren May 30, 2023 pm 02:40 PM

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

So implementieren Sie verteilte Sperren mit Redis in SpringBoot So implementieren Sie verteilte Sperren mit Redis in SpringBoot Jun 03, 2023 am 08:16 AM

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

So lösen Sie das Problem, dass Springboot nach dem Einlesen in ein JAR-Paket nicht auf die Datei zugreifen kann So lösen Sie das Problem, dass Springboot nach dem Einlesen in ein JAR-Paket nicht auf die Datei zugreifen kann Jun 03, 2023 pm 04:38 PM

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

So implementieren Sie Springboot+Mybatis-plus, ohne SQL-Anweisungen zum Hinzufügen mehrerer Tabellen zu verwenden So implementieren Sie Springboot+Mybatis-plus, ohne SQL-Anweisungen zum Hinzufügen mehrerer Tabellen zu verwenden Jun 02, 2023 am 11:07 AM

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

Vergleich und Differenzanalyse zwischen SpringBoot und SpringMVC Vergleich und Differenzanalyse zwischen SpringBoot und SpringMVC Dec 29, 2023 am 11:02 AM

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

Wie SpringBoot Redis anpasst, um die Cache-Serialisierung zu implementieren Wie SpringBoot Redis anpasst, um die Cache-Serialisierung zu implementieren Jun 03, 2023 am 11:32 AM

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

So erhalten Sie den Wert in application.yml in Springboot So erhalten Sie den Wert in application.yml in Springboot Jun 03, 2023 pm 06:43 PM

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

See all articles