精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

SpringBoot攔截器和動態代理有什么區別?

開發 前端
在 Spring Boot 中,攔截器和動態代理都是用來實現功能增強的,但二者沒有任何關聯關系,它的區別主要體現在使用范圍、實現原理、加入時機和使用的難易程度都是不同的。

在 Spring Boot 中,攔截器和動態代理都是用來實現功能增強的,所以在很多時候,有人會認為攔截器的底層是通過動態代理實現的,所以本文就來盤點一下他們兩的區別,以及攔截器的底層實現。

1、攔截器

攔截器(Interceptor)準確來說在 Spring MVC 中的一個很重要的組件,用于攔截 Controller 的請求。它的主要作用有以下幾個:

  • 權限驗證:驗證用戶是否登錄、是否有權限訪問某個接口。
  • 日志記錄:記錄請求信息的日志,如請求參數,響應信息等。
  • 性能監控:監控系統的運行性能,如慢查詢接口等。
  • 通用行為:插入一些通用的行為,比如開發環境忽略某些請求。

典型的使用場景是身份認證、授權檢查、請求日志記錄等。

(1)攔截器實現

在 Spring Boot 中攔截器的實現分為兩步:

  • 創建一個普通的攔截器,實現 HandlerInterceptor 接口,并重寫接口中的相關方法。
  • 將上一步創建的攔截器加入到 Spring Boot 的配置文件中,并配置攔截規則。

具體實現如下。

實現自定義攔截器

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class TestInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("攔截器:執行 preHandle 方法。");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("攔截器:執行 postHandle 方法。");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("攔截器:執行 afterCompletion 方法。");
    }
}

其中:

  • boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handle):在請求方法執行前被調用,也就是調用目標方法之前被調用。比如我們在操作數據之前先要驗證用戶的登錄信息,就可以在此方法中實現,如果驗證成功則返回 true,繼續執行數據操作業務;否則就返回 false,后續操作數據的業務就不會被執行了。
  • void postHandle(HttpServletRequest request, HttpServletResponse response, Object handle,ModelAndView modelAndView):調用請求方法之后執行,但它會在 DispatcherServlet 進行渲染視圖之前被執行。
  • void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex):會在整個請求結束之后再執行,也就是在 DispatcherServlet 渲染了對應的視圖之后再執行。

配置攔截規則

然后,我們再將上面的攔截器注入到項目配置文件中,并設置相應攔截規則,具體實現代碼如下:

import org.springframework.beans.factory.annotation.Autowired;
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 AppConfig implements WebMvcConfigurer {

    // 注入攔截器
    @Autowired
    private TestInterceptor testInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(testInterceptor) // 添加攔截器
                .addPathPatterns("/**"); // 攔截所有地址
          .excludePathPatterns("/login"); // 放行接口
    }
}

這樣我們的攔截器就實現完了。

(2)攔截器實現原理

Spring Boot 攔截器是基于 Java 的 Servlet 規范實現的,通過實現 HandlerInterceptor 接口來實現攔截器功能。

在 Spring Boot 框架的執行流程中,攔截器被注冊在 DispatcherServlet 的 doDispatch() 方法中,該方法是 Spring Boot 框架的核心方法,用于處理請求和響應。

程序每次執行時都會調用 doDispatch() 方法時,并驗證攔截器(鏈),之后再根據攔截器返回的結果,進行下一步的處理。如果返回的是 true,那么繼續調用目標方法,反之則會直接返回驗證失敗給前端。

doDispatch  源碼實現如下:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    HttpServletRequest processedRequest = request;
    HandlerExecutionChain mappedHandler = null;
    boolean multipartRequestParsed = false;
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

    try {
        try {
            ModelAndView mv = null;
            Object dispatchException = null;

            try {
                processedRequest = this.checkMultipart(request);
                multipartRequestParsed = processedRequest != request;
                mappedHandler = this.getHandler(processedRequest);
                if (mappedHandler == null) {
                    this.noHandlerFound(processedRequest, response);
                    return;
                }

                HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                String method = request.getMethod();
                boolean isGet = HttpMethod.GET.matches(method);
                if (isGet || HttpMethod.HEAD.matches(method)) {
                    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                    if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                        return;
                    }
                }

                // 調用預處理【重點】
                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }

                // 執行 Controller 中的業務
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }

                this.applyDefaultViewName(processedRequest, mv);
                mappedHandler.applyPostHandle(processedRequest, response, mv);
            } catch (Exception var20) {
                dispatchException = var20;
            } catch (Throwable var21) {
                dispatchException = new NestedServletException("Handler dispatch failed", var21);
            }

            this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
        } catch (Exception var22) {
            this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
        } catch (Throwable var23) {
            this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
        }

    } finally {
        if (asyncManager.isConcurrentHandlingStarted()) {
            if (mappedHandler != null) {
                mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
            }
        } else if (multipartRequestParsed) {
            this.cleanupMultipart(processedRequest);
        }

    }
}

從上述源碼可以看出在開始執行 Controller 之前,會先調用 預處理方法 applyPreHandle,而 applyPreHandle 方法的實現源碼如下:

boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
    for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex = i++) {
        // 獲取項目中使用的攔截器 HandlerInterceptor
        HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
        if (!interceptor.preHandle(request, response, this.handler)) {
            this.triggerAfterCompletion(request, response, (Exception)null);
            return false;
        }
    }
    return true;
}

從上述源碼可以看出,在 applyPreHandle 中會獲取所有的攔截器 HandlerInterceptor 并執行攔截器中的 preHandle 方法,這樣就會咱們前面定義的攔截器對應上了,如下圖所示:

此時用戶登錄權限的驗證方法就會執行,這就是攔截器的執行過程。因此,可以得出結論,攔截器的實現主要是依賴 Servlet 或 Spring 執行流程來進行攔截和功能增強的。

2、動態代理

動態代理是一種設計模式,它是指在運行時提供代理對象,來擴展目標對象的功能。在 Spring 中的,動態代理的實現手段有以下兩種:

  • JDK 動態代理:通過反射機制生成代理對象,目標對象必須實現接口。
  • CGLIB 動態代理:通過生成目標類的子類來實現代理,不要求目標對象實現接口。

動態代理的主要作用包括:

  • 擴展目標對象的功能:如添加日志、驗證參數等。
  • 控制目標對象的訪問:如進行權限控制。
  • 延遲加載目標對象:在需要時才實例化目標對象。
  • 遠程代理:將請求轉發到遠程的目標對象上。

JDK 動態代理和 CGLIB 的區別詳見:www.javacn.site/interview/spring/jdk_cglib.html

3、攔截器 VS 動態代理

因此,我們可以得出結論,攔截器和動態代理雖然都是用來實現功能增強的,但二者完全不同,他們的主要區別體現在以下幾點:

  • 使用范圍不同:攔截器通常用于 Spring MVC 中,主要用于攔截 Controller 請求。動態代理可以使用在 Bean 中,主要用于提供 bean 的代理對象,實現對 bean 方法的攔截。
  • 實現原理不同:攔截器是通過 HandlerInterceptor 接口來實現的,主要是通過 afterCompletion、postHandle、preHandle 這三個方法在請求前后進行攔截處理。動態代理主要有 JDK 動態代理和 CGLIB 動態代理,JDK 通過反射生成代理類;CGLIB 通過生成被代理類的子類來實現代理。
  • 加入時機不同:攔截器是在運行階段動態加入的;動態代理是在編譯期或運行期生成的代理類。
  • 使用難易程度不同:攔截器相對簡單,通過實現接口即可使用。動態代理稍微復雜,需要了解動態代理的實現原理,然后通過相應的 api 實現。

小結

在 Spring Boot 中,攔截器和動態代理都是用來實現功能增強的,但二者沒有任何關聯關系,它的區別主要體現在使用范圍、實現原理、加入時機和使用的難易程度都是不同的。

責任編輯:姜華 來源: Java中文社群
相關推薦

2023-02-20 07:19:14

2023-05-29 07:36:04

Java過濾器攔截器

2020-07-20 09:18:43

存儲數據技術

2009-02-12 15:33:00

代理服務器HTTPSOCKS

2021-05-16 14:26:08

RPAIPACIO

2024-05-27 00:40:00

2024-09-09 13:10:14

2022-02-27 15:33:22

安全CASBSASE

2021-12-17 14:40:02

while(1)for(;;)語言

2024-03-05 18:59:59

前端開發localhost

2022-08-02 08:23:37

SessionCookies

2022-09-08 18:38:26

LinuxWindowsmacOS

2020-11-09 14:07:53

PyQtQt編程

2020-03-09 20:56:19

LoRaLoRaWAN無線技術

2022-09-07 18:32:57

并發編程線程

2022-06-06 14:53:02

LoRaLoRaWAN

2025-05-09 08:20:50

2025-03-10 09:30:00

SpringJava開發

2023-12-15 09:21:17

ObjectJavaString
點贊
收藏

51CTO技術棧公眾號

1313精品午夜理伦电影| 黄色网页网址在线免费| 鲁大师影院一区二区三区| 亚洲美女又黄又爽在线观看| 成年人黄色片视频| wwwww在线观看免费视频| 激情亚洲综合在线| 韩国美女主播一区| 嘿嘿视频在线观看| 最新精品在线| 欧美午夜在线观看| 无码人妻少妇伦在线电影| 邻家有女韩剧在线观看国语| 九色综合狠狠综合久久| 性色av一区二区三区在线观看| 一级片手机在线观看| 日本午夜精品久久久久| 精品久久久久久久大神国产| 亚洲精品在线观看免费| 日本精品一区二区在线观看| 免费精品视频在线| 91精品国产91久久久久福利| 天天色影综合网| 欧美美女黄色| 精品欧美乱码久久久久久| 日本在线视频www| 丁香高清在线观看完整电影视频| 中文字幕国产一区| 狠狠色综合一区二区| 国产精品羞羞答答在线| 日韩经典中文字幕一区| 久久噜噜噜精品国产亚洲综合| 99自拍偷拍视频| 秋霞影视一区二区三区| 精品久久久久久久久久久久包黑料 | 91女厕偷拍女厕偷拍高清| 91九色国产社区在线观看| 国产精品免费精品一区| 亚洲第一黄色| 色综合久久久888| 亚洲不卡在线播放| 日韩电影二区| 国产亚洲xxx| 新91视频在线观看| 特黄特色欧美大片| 亚洲精品乱码久久久久久金桔影视 | 欧美xxxx老人做受| 久久精品一二三四| 不卡一区视频| 欧美男男青年gay1069videost| 欧美黄色一级片视频| 裤袜国产欧美精品一区| 精品国产精品自拍| 亚洲熟妇av日韩熟妇在线| 成人影院在线播放| 亚洲成人黄色影院| 日韩av高清在线看片| 久久一卡二卡| 亚洲1区2区3区4区| 成人毛片一区二区| 深夜在线视频| 欧美午夜精品久久久久久人妖| 欧美亚洲日本一区二区三区 | 免费av一区| 亚洲精品中文字幕女同| 好吊日免费视频| 久久精品亚洲成在人线av网址| 精品剧情在线观看| 朝桐光av一区二区三区| 婷婷精品在线观看| 夜夜嗨av色综合久久久综合网| 五月天综合视频| 日本一区二区在线看| 精品国产一区二区三区久久狼黑人 | 国产精品久久久久久久久夜色| 久久激情婷婷| 国产欧美久久久久久| 91麻豆成人精品国产| 国产乱码精品一区二区三区av| 91久久久一线二线三线品牌| 国产 日韩 欧美 综合| 久久综合色天天久久综合图片| 蜜桃在线一区二区三区精品| a√在线中文网新版址在线| 国产亚洲女人久久久久毛片| 午夜在线视频免费观看| 538在线精品| 欧美性大战久久久久久久 | 日韩少妇高潮抽搐| 国产亚洲精品码| 亚洲特级毛片| 国产精品国产三级国产aⅴ浪潮| 在线观看国产精品视频| 国产乱人伦偷精品视频免下载| 国内精品久久国产| lutube成人福利在线观看| 亚洲精品你懂的| av女优在线播放| 国产成人77亚洲精品www| 欧美一三区三区四区免费在线看| 久久一区二区电影| 日韩欧美大片| 久久免费成人精品视频| 在线观看中文字幕网站| 成人白浆超碰人人人人| 婷婷五月色综合| av蜜臀在线| 欧美日韩国产不卡| 成人免费无码大片a毛片| 99热精品久久| 青草青草久热精品视频在线网站| 国产免费av观看| 久久久夜色精品亚洲| 午夜久久久久久久久久久| 欧美黑人疯狂性受xxxxx野外| 欧美精品九九99久久| 欧美成人午夜精品免费| 综合一区二区三区| 国产精品激情自拍| 午夜影院免费视频| 亚洲综合成人在线| 久久久久xxxx| 精品久久久久久久| 欧美专区在线播放| 国产小视频一区| 亚洲免费在线视频一区 二区| 激情六月丁香婷婷| 老牛国内精品亚洲成av人片| 久久国产加勒比精品无码| 成人h动漫精品一区二区下载| 成人av综合一区| av中文字幕av| 亚洲人成777| 最近2019年好看中文字幕视频| 天天干天天干天天干天天| 成人午夜激情片| 天天做天天躁天天躁| 电影中文字幕一区二区| 最新69国产成人精品视频免费| 日本天堂网在线| 成人亚洲一区二区一| 免费看污污视频| 亚洲超碰在线观看| 欧美成人激情视频免费观看| 97精品人妻一区二区三区在线| 国产三级精品三级| 国产精品igao| jiujiure精品视频播放| 国产精品第100页| 国产高清av在线| 色激情天天射综合网| 五月开心播播网| 欧美一级专区| 日韩高清av| 粉嫩91精品久久久久久久99蜜桃| 中文字幕精品—区二区| 在线观看免费高清视频| 亚洲色图在线播放| 一级片免费在线观看视频| 亚洲经典一区| 成人h视频在线观看| 欧美人与性动交α欧美精品济南到| 日韩你懂的在线播放| 久久久.www| 成人黄色在线看| 精品99在线视频| 欧美精品系列| 91在线观看免费网站| 污污的视频在线观看| 精品91自产拍在线观看一区| 中文字幕第15页| 欧美国产一区在线| 一级黄色片在线免费观看| 韩日成人在线| 免费看成人片| 欧美成a人片免费观看久久五月天| 色噜噜狠狠色综合网图区| 国产高中女学生第一次| 亚洲v日本v欧美v久久精品| 欧类av怡春院| 日本aⅴ亚洲精品中文乱码| 欧美日韩一级在线| 99精品中文字幕在线不卡| 18一19gay欧美视频网站| 国产51人人成人人人人爽色哟哟| 欧美精品久久一区二区三区| 国产成人啪精品午夜在线观看| 久久男人中文字幕资源站| 一区二区三区四区毛片| 亚洲欧洲另类| 亚洲人成人77777线观看| 中文字幕av一区二区三区四区| 91po在线观看91精品国产性色| 91九色在线porn| 精品乱人伦小说| 中国女人一级一次看片| 亚洲综合成人网| 国产精品一二三区在线观看| 国产精品18久久久久久久久久久久| 六月婷婷在线视频| 99久久亚洲精品| 美国av一区二区三区| 久久天堂久久| 国产精品久久久久久中文字| 欧美大片黄色| xxav国产精品美女主播| 天堂√在线中文官网在线| 欧美一区二区日韩一区二区| 国产一级一级国产| 亚洲一区在线看| 亚洲综合第一区| 91免费在线看| 日本xxxx免费| 久久精品久久久精品美女| 青青艹视频在线| 欧美在线亚洲综合一区| 天堂精品一区二区三区| 精品亚洲免a| 亚洲伊人成综合成人网| a成人v在线| 热re91久久精品国99热蜜臀| 秋霞在线视频| 久久久国产精品x99av| 国产高清免费在线播放| 日韩精品极品视频| 手机看片一区二区| 精品乱人伦小说| 亚洲AV无码一区二区三区性| 欧美福利视频一区| 一本色道久久综合精品婷婷| 色悠悠久久综合| 黄网在线观看视频| 亚洲第一福利视频在线| 免费人成在线观看| 亚洲精品少妇30p| 制服丨自拍丨欧美丨动漫丨| 国产日韩欧美制服另类| 在线不卡av电影| 99精品视频免费在线观看| 亚洲免费观看在线| 国产精品18久久久久| 久久久久久久久久一区| 麻豆久久久久久久| 老司机午夜性大片| 美国三级日本三级久久99| 亚洲激情在线观看视频| 日韩中文字幕麻豆| 日本a√在线观看| 奇米影视一区二区三区| 校园春色 亚洲色图| 日本成人在线视频网站| 69久久久久久| 久久99精品网久久| 亚洲五月激情网| 国产美女娇喘av呻吟久久| 中文字幕一二三| 国产99精品视频| 五月天激情小说| 2021久久国产精品不只是精品| 国产精品一区二区入口九绯色| 91蝌蚪porny九色| 男人舔女人下部高潮全视频| 国产女人18毛片水真多成人如厕 | 国产午夜亚洲精品午夜鲁丝片 | www.超碰在线.com| 亚洲成年人在线| 无码国产精品96久久久久| 亚洲美女在线视频| 高清性色生活片在线观看| 日韩午夜在线视频| caopo在线| 久久久久亚洲精品国产| 亚洲欧洲美洲av| 国产精品一区二区久久国产| 国产激情精品一区二区三区| 国产伦精品一区二区三区照片91 | 欧美中日韩免费视频| 青青草国产免费一区二区下载 | 欧洲精品中文字幕| ,亚洲人成毛片在线播放| 欧美第一区第二区| 污污的视频网站在线观看| 中国china体内裑精亚洲片| 1区2区3区在线视频| 97在线免费观看视频| 成人激情综合| 7777精品伊久久久大香线蕉语言 | 国产精品主播直播| 91porn在线| 国产片一区二区| 久久黄色小视频| 在线一区二区视频| 精品人妻一区二区三区浪潮在线| 日韩精品久久久久久久玫瑰园| 色视频在线免费观看| 色综合91久久精品中文字幕| 亚洲欧洲自拍| 亚洲伊人久久大香线蕉av| 国产欧美日韩精品高清二区综合区| 一区在线电影| 国产农村妇女精品一区二区| 国内自拍第二页| 2020国产精品| 精品一区在线视频| 欧美日韩久久久久久| 天堂在线视频免费| 久久精品免费播放| 我爱我色成人网| 国产精品乱码| 亚洲成人tv| 精品999在线| 99re在线精品| 国产在线视频你懂的| 欧美丝袜丝交足nylons图片| 天天干天天干天天干| 久久视频在线免费观看| 影视一区二区三区| 久久青青草综合| 在线观看不卡| 波多野结衣网页| 国产精品久久久久久一区二区三区| 成年免费在线观看| 日韩欧美国产一区二区三区| 色大18成网站www在线观看| 欧美在线视频免费观看| 东京久久高清| 日本男女交配视频| 国产一区二区免费看| 四虎884aa成人精品| 欧美亚洲一区二区在线观看| 欧洲综合视频| 97人洗澡人人免费公开视频碰碰碰| 国产电影一区| 国产精品波多野结衣| 久久精品国产**网站演员| 极品久久久久久久| 在线一区二区视频| 国产天堂在线| 国产精品精品国产| av中文字幕一区二区| 无码人妻丰满熟妇区毛片18| 久久这里只精品最新地址| 在线观看国产亚洲| 日韩精品中文字幕久久臀| а√天堂中文资源在线bt| 国产精成人品localhost| 狠狠爱成人网| 四虎精品一区二区| 婷婷六月综合网| 日本韩国一区| 国产97在线视频| 日韩中文首页| 伊人免费视频二| 一区二区在线观看免费| 亚洲精品国产精品乱码不卡| 久久99国产精品久久久久久久久| 日本免费精品| 日b视频免费观看| 成人ar影院免费观看视频| 男人的天堂一区二区| 亚洲精品日韩欧美| 我爱我色成人网| 中文字幕精品一区日韩| 韩国理伦片一区二区三区在线播放| 国产麻豆a毛片| 日韩一区二区在线看| 欧美男男video| 欧美精品一区二区三区四区五区| 日韩电影在线观看电影| 娇小11一12╳yⅹ╳毛片| 日韩一级大片在线| 极品在线视频| 亚洲高清123| 国产高清不卡二三区| 国产成人免费观看视频 | 亚洲日本精品视频| 欧美日韩mp4| 98色花堂精品视频在线观看| 欧美日韩精品免费看| 久久精品久久99精品久久| 2018天天弄| 日韩av在线免费观看| 外国电影一区二区| 成人高清dvd| 91麻豆福利精品推荐| 国产又爽又黄又嫩又猛又粗| 欧美激情精品久久久久久蜜臀| 天天做夜夜做人人爱精品| 日本超碰在线观看| 亚洲成在人线在线播放| 成人欧美亚洲| 国产精品免费一区二区| 日韩国产欧美在线播放| 精品欧美一区二区久久久久| 亚洲欧美国产视频| 欧美第一在线视频| 国产熟人av一二三区| 亚洲高清免费在线| 婷婷在线视频| 蜜桃欧美视频|