日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

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

來源: 責編: 時間:2023-09-18 21:41:16 436觀看
導讀在 Spring Boot 中,攔截器和動態代理都是用來實現功能增強的,所以在很多時候,有人會認為攔截器的底層是通過動態代理實現的,所以本文就來盤點一下他們兩的區別,以及攔截器的底層實現。1、攔截器攔截器(Interceptor)準確來說

ffr28資訊網——每日最新資訊28at.com

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

1、攔截器

攔截器(Interceptor)準確來說在 Spring MVC 中的一個很重要的組件,用于攔截 Controller 的請求。它的主要作用有以下幾個:ffr28資訊網——每日最新資訊28at.com

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

典型的使用場景是身份認證、授權檢查、請求日志記錄等。ffr28資訊網——每日最新資訊28at.com

(1)攔截器實現

在 Spring Boot 中攔截器的實現分為兩步:ffr28資訊網——每日最新資訊28at.com

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

具體實現如下。ffr28資訊網——每日最新資訊28at.com

實現自定義攔截器

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;@Componentpublic 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 方法。");    }}

其中:ffr28資訊網——每日最新資訊28at.com

  • 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 渲染了對應的視圖之后再執行。

配置攔截規則

然后,我們再將上面的攔截器注入到項目配置文件中,并設置相應攔截規則,具體實現代碼如下:ffr28資訊網——每日最新資訊28at.com

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;@Configurationpublic class AppConfig implements WebMvcConfigurer {    // 注入攔截器    @Autowired    private TestInterceptor testInterceptor;    @Override    public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(testInterceptor) // 添加攔截器                .addPathPatterns("/**"); // 攔截所有地址          .excludePathPatterns("/login"); // 放行接口    }}

這樣我們的攔截器就實現完了。ffr28資訊網——每日最新資訊28at.com

(2)攔截器實現原理

Spring Boot 攔截器是基于 Java 的 Servlet 規范實現的,通過實現 HandlerInterceptor 接口來實現攔截器功能。ffr28資訊網——每日最新資訊28at.com

在 Spring Boot 框架的執行流程中,攔截器被注冊在 DispatcherServlet 的 doDispatch() 方法中,該方法是 Spring Boot 框架的核心方法,用于處理請求和響應。ffr28資訊網——每日最新資訊28at.com

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

doDispatch  源碼實現如下:ffr28資訊網——每日最新資訊28at.com

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 方法的實現源碼如下:ffr28資訊網——每日最新資訊28at.com

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 方法,這樣就會咱們前面定義的攔截器對應上了,如下圖所示:ffr28資訊網——每日最新資訊28at.com

ffr28資訊網——每日最新資訊28at.com

此時用戶登錄權限的驗證方法就會執行,這就是攔截器的執行過程。因此,可以得出結論,攔截器的實現主要是依賴 Servlet 或 Spring 執行流程來進行攔截和功能增強的。ffr28資訊網——每日最新資訊28at.com

2、動態代理

動態代理是一種設計模式,它是指在運行時提供代理對象,來擴展目標對象的功能。在 Spring 中的,動態代理的實現手段有以下兩種:ffr28資訊網——每日最新資訊28at.com

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

動態代理的主要作用包括:ffr28資訊網——每日最新資訊28at.com

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

ffr28資訊網——每日最新資訊28at.com

JDK 動態代理和 CGLIB 的區別詳見:www.javacn.site/interview/spring/jdk_cglib.htmlffr28資訊網——每日最新資訊28at.com

ffr28資訊網——每日最新資訊28at.com

3、攔截器 VS 動態代理

因此,我們可以得出結論,攔截器和動態代理雖然都是用來實現功能增強的,但二者完全不同,他們的主要區別體現在以下幾點:ffr28資訊網——每日最新資訊28at.com

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

小結

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

本文鏈接:http://m.www897cc.com/showinfo-26-10450-0.htmlSpringBoot攔截器和動態代理有什么區別?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Go并發可視化解釋 – select語句

下一篇: Serverless vs Containers:哪個適合您的業務?

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
国产毛片一区| 欧美精品尤物在线| 亚洲在线视频免费观看| 亚洲欧美激情诱惑| 久久精品欧洲| 欧美99在线视频观看| 欧美经典一区二区| 欧美日韩在线视频一区| 国产欧美精品| 亚洲电影视频在线| 国产精品99久久不卡二区 | 久久精品国产69国产精品亚洲| 久久久久国产精品一区| 欧美巨乳在线| 国产伦精品一区二区三区视频孕妇 | 久久久一本精品99久久精品66| 欧美日韩不卡一区| 国产亚洲激情视频在线| 亚洲精品视频免费在线观看| 亚洲性视频h| 狼人天天伊人久久| 国产精品白丝av嫩草影院 | 亚洲欧美日韩国产综合在线 | 久久久久久网| 国产精品va在线| 在线观看三级视频欧美| 亚洲尤物在线视频观看| 美女精品国产| 国产精品综合网站| 日韩亚洲欧美精品| 久久久999国产| 欧美偷拍一区二区| 亚洲国产日韩一区二区| 亚洲欧美国产精品专区久久| 欧美电影在线观看| 国产一区二区三区成人欧美日韩在线观看| 日韩一级免费| 巨乳诱惑日韩免费av| 国产欧美日韩中文字幕在线| 日韩一级大片| 免费观看国产成人| 国产日韩欧美视频在线| 中文在线不卡| 欧美激情综合亚洲一二区| 韩日视频一区| 亚欧成人在线| 国产精品v欧美精品v日韩 | 亚洲欧美日韩一区二区| 欧美日韩黄视频| 亚洲成色999久久网站| 欧美一区二区精品| 欧美性猛交一区二区三区精品| 91久久精品一区二区三区| 久久久久一区| 国产在线不卡视频| 亚洲欧美精品一区| 欧美视频中文一区二区三区在线观看| 亚洲国产裸拍裸体视频在线观看乱了| 久久久久国产精品一区三寸| 国产美女精品一区二区三区 | 午夜精品在线| 欧美香蕉视频| 99国产精品国产精品毛片| 欧美 日韩 国产一区二区在线视频| 国产亚洲综合性久久久影院| 亚洲综合日韩在线| 欧美视频中文字幕| 一本色道久久综合亚洲精品高清 | 欧美另类一区| 亚洲欧洲精品天堂一级| 美国成人直播| 在线高清一区| 久久天天狠狠| 一色屋精品视频在线观看网站| 欧美一区在线直播| 国产色婷婷国产综合在线理论片a| 在线视频一区二区| 欧美乱大交xxxxx| 亚洲精品免费在线| 欧美精品aa| 日韩视频二区| 欧美日韩免费一区二区三区| 99精品热6080yy久久| 欧美日韩免费观看一区=区三区| 亚洲美女毛片| 欧美日韩在线观看一区二区| 一区二区三区日韩精品视频| 欧美午夜宅男影院| 亚洲综合日韩在线| 国产三级欧美三级| 久久久久久久久久久久久女国产乱 | 日韩视频免费观看高清完整版| 欧美成人精品一区二区| 亚洲欧洲日本国产| 欧美日本国产在线| 亚洲网友自拍| 国产美女诱惑一区二区| 久久激情婷婷| 亚洲第一免费播放区| 欧美—级高清免费播放| 一本久道久久综合婷婷鲸鱼| 国产精品久久福利| 欧美一区二区三区男人的天堂| 国内精品视频在线观看| 看片网站欧美日韩| 日韩视频在线永久播放| 国产精品av久久久久久麻豆网| 香蕉国产精品偷在线观看不卡 | 一区免费在线| 欧美精品福利在线| 亚洲一区二区三区视频| 国产日韩欧美在线播放| 久久亚洲不卡| 亚洲精品在线视频观看| 国产精品久久久久久久免费软件| 欧美一区二区三区视频在线 | 亚洲久久视频| 欧美午夜在线视频| 久久国产福利国产秒拍| 亚洲国产影院| 国产精品剧情在线亚洲| 久久精品亚洲热| 亚洲三级网站| 国产久一道中文一区| 免费成人黄色| 亚洲综合成人在线| 在线观看视频亚洲| 欧美日韩一区在线观看| 久久成人av少妇免费| 亚洲国产一区二区a毛片| 欧美日韩午夜精品| 久久国产加勒比精品无码| 亚洲精品免费看| 国产午夜精品久久久久久免费视| 免费不卡欧美自拍视频| 亚洲一本大道在线| 极品尤物av久久免费看| 欧美视频在线免费| 久久久久综合网| 一区二区日韩精品| 极品尤物久久久av免费看| 欧美日韩人人澡狠狠躁视频| 久久久久99精品国产片| 中国亚洲黄色| 亚洲成人在线视频网站| 国产精品久久久久久亚洲调教 | 国产亚洲精品久久久久久| 欧美母乳在线| 久久精品一区二区三区四区| 99国产精品国产精品毛片| 狠色狠色综合久久| 国产精品激情av在线播放| 久久一区二区三区国产精品 | 欧美一级电影久久| 日韩亚洲成人av在线| 国语自产精品视频在线看| 欧美亚洲第一页| 欧美14一18处毛片| 久久国产精品亚洲va麻豆| 一本一本大道香蕉久在线精品| 一区二区三区在线观看国产| 国产精品无码永久免费888| 欧美日本不卡高清| 蜜桃av综合| 久久久久www| 欧美在线观看一区| 亚洲视频高清| 亚洲精选成人| 亚洲国产精品一区二区www在线| 国产一区二区三区成人欧美日韩在线观看 | 国产欧美精品va在线观看| 欧美日韩视频专区在线播放 | 国产伦精品一区二区三区四区免费| 欧美久久成人| 欧美国产大片| 老鸭窝毛片一区二区三区| 欧美专区亚洲专区| 亚洲欧美日韩国产综合在线| 99综合精品| 亚洲精品一二区| 亚洲欧洲另类| 亚洲区第一页| 亚洲啪啪91| 亚洲欧洲一区二区三区在线观看 | 亚洲精品影院在线观看| 亚洲国产精品激情在线观看| 国产在线拍偷自揄拍精品| 国产模特精品视频久久久久 | 国产欧美一区二区三区在线老狼| 国产精品久久久久999| 欧美色区777第一页| 欧美日韩视频在线第一区| 欧美日韩调教| 欧美午夜寂寞影院| 欧美日韩在线播放| 欧美网站在线观看| 国产精品久久久久久久久久久久 | 亚洲国产成人精品女人久久久 | 国产人成精品一区二区三| 国产老女人精品毛片久久| 国产欧美日韩在线| 国产丝袜一区二区三区| 国产亚洲综合精品| 国内精品视频在线播放|