国产精品嫩草99av在线_一区在线视频观看_欧美高清一区_欧美 日韩 国产 一区_99精品欧美一区二区三区_久久大香伊蕉在人线观看热2_一色屋精品视频在线观看网站_在线亚洲国产精品网站_亚洲区一区二区三区_你懂的视频一区二区

當(dāng)前位置:首頁 > 科技  > 軟件

SpringBoot攔截器和動(dòng)態(tài)代理有什么區(qū)別?

來源: 責(zé)編: 時(shí)間:2023-09-18 21:41:16 434觀看
導(dǎo)讀在 Spring Boot 中,攔截器和動(dòng)態(tài)代理都是用來實(shí)現(xiàn)功能增強(qiáng)的,所以在很多時(shí)候,有人會(huì)認(rèn)為攔截器的底層是通過動(dòng)態(tài)代理實(shí)現(xiàn)的,所以本文就來盤點(diǎn)一下他們兩的區(qū)別,以及攔截器的底層實(shí)現(xiàn)。1、攔截器攔截器(Interceptor)準(zhǔn)確來說

sTB28資訊網(wǎng)——每日最新資訊28at.com

在 Spring Boot 中,攔截器和動(dòng)態(tài)代理都是用來實(shí)現(xiàn)功能增強(qiáng)的,所以在很多時(shí)候,有人會(huì)認(rèn)為攔截器的底層是通過動(dòng)態(tài)代理實(shí)現(xiàn)的,所以本文就來盤點(diǎn)一下他們兩的區(qū)別,以及攔截器的底層實(shí)現(xiàn)。sTB28資訊網(wǎng)——每日最新資訊28at.com

1、攔截器

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

  • 權(quán)限驗(yàn)證:驗(yàn)證用戶是否登錄、是否有權(quán)限訪問某個(gè)接口。
  • 日志記錄:記錄請(qǐng)求信息的日志,如請(qǐng)求參數(shù),響應(yīng)信息等。
  • 性能監(jiān)控:監(jiān)控系統(tǒng)的運(yùn)行性能,如慢查詢接口等。
  • 通用行為:插入一些通用的行為,比如開發(fā)環(huán)境忽略某些請(qǐng)求。

典型的使用場(chǎng)景是身份認(rèn)證、授權(quán)檢查、請(qǐng)求日志記錄等。sTB28資訊網(wǎng)——每日最新資訊28at.com

(1)攔截器實(shí)現(xiàn)

在 Spring Boot 中攔截器的實(shí)現(xiàn)分為兩步:sTB28資訊網(wǎng)——每日最新資訊28at.com

  • 創(chuàng)建一個(gè)普通的攔截器,實(shí)現(xiàn) HandlerInterceptor 接口,并重寫接口中的相關(guān)方法。
  • 將上一步創(chuàng)建的攔截器加入到 Spring Boot 的配置文件中,并配置攔截規(guī)則。

具體實(shí)現(xiàn)如下。sTB28資訊網(wǎng)——每日最新資訊28at.com

實(shí)現(xiàn)自定義攔截器

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("攔截器:執(zhí)行 preHandle 方法。");        return true;    }    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {        System.out.println("攔截器:執(zhí)行 postHandle 方法。");    }    @Override    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {        System.out.println("攔截器:執(zhí)行 afterCompletion 方法。");    }}

其中:sTB28資訊網(wǎng)——每日最新資訊28at.com

  • boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handle):在請(qǐng)求方法執(zhí)行前被調(diào)用,也就是調(diào)用目標(biāo)方法之前被調(diào)用。比如我們?cè)诓僮鲾?shù)據(jù)之前先要驗(yàn)證用戶的登錄信息,就可以在此方法中實(shí)現(xiàn),如果驗(yàn)證成功則返回 true,繼續(xù)執(zhí)行數(shù)據(jù)操作業(yè)務(wù);否則就返回 false,后續(xù)操作數(shù)據(jù)的業(yè)務(wù)就不會(huì)被執(zhí)行了。
  • void postHandle(HttpServletRequest request, HttpServletResponse response, Object handle,ModelAndView modelAndView):調(diào)用請(qǐng)求方法之后執(zhí)行,但它會(huì)在 DispatcherServlet 進(jìn)行渲染視圖之前被執(zhí)行。
  • void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex):會(huì)在整個(gè)請(qǐng)求結(jié)束之后再執(zhí)行,也就是在 DispatcherServlet 渲染了對(duì)應(yīng)的視圖之后再執(zhí)行。

配置攔截規(guī)則

然后,我們?cè)賹⑸厦娴臄r截器注入到項(xiàng)目配置文件中,并設(shè)置相應(yīng)攔截規(guī)則,具體實(shí)現(xiàn)代碼如下:sTB28資訊網(wǎng)——每日最新資訊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"); // 放行接口    }}

這樣我們的攔截器就實(shí)現(xiàn)完了。sTB28資訊網(wǎng)——每日最新資訊28at.com

(2)攔截器實(shí)現(xiàn)原理

Spring Boot 攔截器是基于 Java 的 Servlet 規(guī)范實(shí)現(xiàn)的,通過實(shí)現(xiàn) HandlerInterceptor 接口來實(shí)現(xiàn)攔截器功能。sTB28資訊網(wǎng)——每日最新資訊28at.com

在 Spring Boot 框架的執(zhí)行流程中,攔截器被注冊(cè)在 DispatcherServlet 的 doDispatch() 方法中,該方法是 Spring Boot 框架的核心方法,用于處理請(qǐng)求和響應(yīng)。sTB28資訊網(wǎng)——每日最新資訊28at.com

程序每次執(zhí)行時(shí)都會(huì)調(diào)用 doDispatch() 方法時(shí),并驗(yàn)證攔截器(鏈),之后再根據(jù)攔截器返回的結(jié)果,進(jìn)行下一步的處理。如果返回的是 true,那么繼續(xù)調(diào)用目標(biāo)方法,反之則會(huì)直接返回驗(yàn)證失敗給前端。sTB28資訊網(wǎng)——每日最新資訊28at.com

doDispatch  源碼實(shí)現(xiàn)如下:sTB28資訊網(wǎng)——每日最新資訊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;                    }                }                // 調(diào)用預(yù)處理【重點(diǎn)】                if (!mappedHandler.applyPreHandle(processedRequest, response)) {                    return;                }                // 執(zhí)行 Controller 中的業(yè)務(wù)                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);        }    }}

從上述源碼可以看出在開始執(zhí)行 Controller 之前,會(huì)先調(diào)用 預(yù)處理方法 applyPreHandle,而 applyPreHandle 方法的實(shí)現(xiàn)源碼如下:sTB28資訊網(wǎng)——每日最新資訊28at.com

boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {    for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex = i++) {        // 獲取項(xiàng)目中使用的攔截器 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 中會(huì)獲取所有的攔截器 HandlerInterceptor 并執(zhí)行攔截器中的 preHandle 方法,這樣就會(huì)咱們前面定義的攔截器對(duì)應(yīng)上了,如下圖所示:sTB28資訊網(wǎng)——每日最新資訊28at.com

sTB28資訊網(wǎng)——每日最新資訊28at.com

此時(shí)用戶登錄權(quán)限的驗(yàn)證方法就會(huì)執(zhí)行,這就是攔截器的執(zhí)行過程。因此,可以得出結(jié)論,攔截器的實(shí)現(xiàn)主要是依賴 Servlet 或 Spring 執(zhí)行流程來進(jìn)行攔截和功能增強(qiáng)的。sTB28資訊網(wǎng)——每日最新資訊28at.com

2、動(dòng)態(tài)代理

動(dòng)態(tài)代理是一種設(shè)計(jì)模式,它是指在運(yùn)行時(shí)提供代理對(duì)象,來擴(kuò)展目標(biāo)對(duì)象的功能。在 Spring 中的,動(dòng)態(tài)代理的實(shí)現(xiàn)手段有以下兩種:sTB28資訊網(wǎng)——每日最新資訊28at.com

  • JDK 動(dòng)態(tài)代理:通過反射機(jī)制生成代理對(duì)象,目標(biāo)對(duì)象必須實(shí)現(xiàn)接口。
  • CGLIB 動(dòng)態(tài)代理:通過生成目標(biāo)類的子類來實(shí)現(xiàn)代理,不要求目標(biāo)對(duì)象實(shí)現(xiàn)接口。

動(dòng)態(tài)代理的主要作用包括:sTB28資訊網(wǎng)——每日最新資訊28at.com

  • 擴(kuò)展目標(biāo)對(duì)象的功能:如添加日志、驗(yàn)證參數(shù)等。
  • 控制目標(biāo)對(duì)象的訪問:如進(jìn)行權(quán)限控制。
  • 延遲加載目標(biāo)對(duì)象:在需要時(shí)才實(shí)例化目標(biāo)對(duì)象。
  • 遠(yuǎn)程代理:將請(qǐng)求轉(zhuǎn)發(fā)到遠(yuǎn)程的目標(biāo)對(duì)象上。

sTB28資訊網(wǎng)——每日最新資訊28at.com

JDK 動(dòng)態(tài)代理和 CGLIB 的區(qū)別詳見:www.javacn.site/interview/spring/jdk_cglib.htmlsTB28資訊網(wǎng)——每日最新資訊28at.com

sTB28資訊網(wǎng)——每日最新資訊28at.com

3、攔截器 VS 動(dòng)態(tài)代理

因此,我們可以得出結(jié)論,攔截器和動(dòng)態(tài)代理雖然都是用來實(shí)現(xiàn)功能增強(qiáng)的,但二者完全不同,他們的主要區(qū)別體現(xiàn)在以下幾點(diǎn):sTB28資訊網(wǎng)——每日最新資訊28at.com

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

小結(jié)

在 Spring Boot 中,攔截器和動(dòng)態(tài)代理都是用來實(shí)現(xiàn)功能增強(qiáng)的,但二者沒有任何關(guān)聯(lián)關(guān)系,它的區(qū)別主要體現(xiàn)在使用范圍、實(shí)現(xiàn)原理、加入時(shí)機(jī)和使用的難易程度都是不同的。sTB28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://m.rrqrq.com/showinfo-26-10450-0.htmlSpringBoot攔截器和動(dòng)態(tài)代理有什么區(qū)別?

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

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

下一篇: Serverless vs Containers:哪個(gè)適合您的業(yè)務(wù)?

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 国产精品嫩草99av在线_一区在线视频观看_欧美高清一区_欧美 日韩 国产 一区_99精品欧美一区二区三区_久久大香伊蕉在人线观看热2_一色屋精品视频在线观看网站_在线亚洲国产精品网站_亚洲区一区二区三区_你懂的视频一区二区
国产精品视频九色porn| 中文欧美字幕免费| 午夜电影一区二区| 国内久久精品| 日韩一级视频免费观看在线| 久久精品99国产精品| av成人天堂| 亚洲精品国产精品乱码不99| 国产精品igao视频网网址不卡日韩| 精品噜噜噜噜久久久久久久久试看| 国产一区二区三区黄视频| 91久久精品一区二区三| 亚洲成精国产精品女| 国产伦精品一区二区三区四区免费| 国产精品五月天| 欧美久久成人| 国产拍揄自揄精品视频麻豆| 你懂的视频一区二区| 精品日韩欧美在线| 99久久免费精品高清特色大片| 91精品国产综合久久精品图片 | 国产精品久久久一本精品| 欧美国产激情| 国产精品久久看| 亚洲丰满在线| 洋洋av久久久久久久一区| 99视频一区| 午夜久久久久久久久久一区二区| 老鸭窝毛片一区二区三区| 日本亚洲一区二区| 欧美三区免费完整视频在线观看| 国产精品一区二区免费不卡| 日韩三级免费观看| 99re视频精品| 亚洲视频每日更新| 亚洲欧美日韩专区| 免费看黄色91| 日韩免费电影一区| 欧美日韩日本网| 亚洲综合一区二区三区| 久久久久久黄| 黄色资源网久久资源365| 日韩欧美视频一区| 午夜精品一区二区在线观看| 日韩毛片精品高清免费| 欧美一级播放| 国产伦精品一区二区三区在线观看| 欧美久久久久久久久中文字幕| 粉嫩嫩av羞羞动漫久久久| 国产日韩欧美高清| 国产免费成人| 国产在线不卡一区| 日本一区二区三区国色天香| 99精品视频免费| 精品一区二区三区影院在线午夜| 日韩精品专区在线影院观看| 合欧美一区二区三区| 午夜精品福利久久久| 日韩午夜三级在线| 在线精品在线| 韩国成人在线视频| 欧美国产成人在线| 久热这里只精品99re8久| 高清久久久久久| 成人免费在线视频| 欧美日韩国产天堂| 亚洲午夜精品久久久久久app| 免费视频最近日韩| 国产视频不卡一区| 久久成人国产| 94色蜜桃网一区二区三区| 亚洲国产婷婷综合在线精品| 欧美一卡二卡三卡| 国产欧美不卡| 成人午夜又粗又硬又大| 一区二区三区欧美在线观看| 日韩一区二区免费在线电影| 宅男噜噜噜66国产日韩在线观看| 国产在线国偷精品免费看| 亚洲天天做日日做天天谢日日欢 | 国产精品久99| 91精品国产色综合久久久蜜香臀| 日韩亚洲精品在线| 成人免费视频caoporn| 亚洲成人在线网站| 久久精品一区四区| 91成人免费网站| 精品91久久久久| 福利一区福利二区| 午夜精品福利视频网站| 国产精品入口麻豆原神| 欧美精品三级日韩久久| 国产日韩一区欧美| 欧美一区二视频在线免费观看| 久久精品国产77777蜜臀| 成人欧美一区二区三区1314| 日韩欧美国产综合| 91精品91久久久中77777| 狠狠入ady亚洲精品| 成人午夜精品一区二区三区| 青青草精品视频| 一区二区三区 在线观看视频 | 欧美日韩国产高清一区二区三区 | 国产一区二区三区四区五区美女| 一级日本不卡的影视| 国产日产精品一区| 日韩欧美国产wwwww| 欧美性受极品xxxx喷水| 一区二区三区导航| 国产一区二区中文| 99久久综合狠狠综合久久| 韩国精品免费视频| 日韩va欧美va亚洲va久久| 一区二区在线免费| 中文字幕一区二区三区在线播放| 久久综合狠狠综合久久激情| 在线综合视频播放| 欧美日韩免费在线视频| 一本高清dvd不卡在线观看| 一级成人国产| 激情av一区| 黄色免费成人| 欧美日韩精品免费看| 欧美成人日本| 欧美精品尤物在线| 99久久伊人久久99| 91影院在线观看| 99re热视频这里只精品 | 丝瓜av网站精品一区二区| 一区二区三区四区高清精品免费观看| 国产精品网站在线| 国产精品久久久久久妇女6080| 国产亚洲短视频| 国产色产综合产在线视频| 久久精品人人爽人人爽| www亚洲一区| 国产欧美日韩综合| 日本一区二区视频在线观看| 国产日韩欧美精品电影三级在线| 久久久久国产精品人| 久久免费午夜影院| 亚洲国产精品成人久久综合一区| 国产无遮挡一区二区三区毛片日本| 精品粉嫩超白一线天av| 精品久久久久香蕉网| 久久婷婷成人综合色| 国产精品欧美精品| 亚洲三级在线观看| 洋洋成人永久网站入口| 婷婷丁香久久五月婷婷| 人禽交欧美网站| 石原莉奈一区二区三区在线观看| 日韩国产欧美在线播放| 激情综合网激情| 国产精品亚洲一区二区三区妖精| youjizz国产精品| 欧美激情综合| 国产精品久久国产三级国电话系列| 久久国产日韩欧美| 欧美日韩国产综合一区二区三区| 日韩一区二区三区电影 | 欧美午夜精品一区| 欧美一卡二卡在线观看| 国产区在线观看成人精品| 亚洲三级在线免费| 日韩精品乱码免费| 国产精品一区二区免费不卡| 色综合天天综合网天天狠天天| 在线视频观看日韩| 色一情一伦一子一伦一区| 日韩欧美国产电影| 国产精品嫩草影院com| 亚洲成人你懂的| 国产激情精品久久久第一区二区| 欧美一区二区三区四区在线观看地址 | 精品国产乱子伦一区| 国产精品久久久久久久裸模| 亚洲国产精品精华液网站| 国产一区二区在线视频| 91免费在线看| 老鸭窝毛片一区二区三区| 欧美一区二区福利在线| 1000部国产精品成人观看| 免费在线观看一区| 91免费精品国自产拍在线不卡| 国产精品毛片va一区二区三区| 51精品国自产在线| 中文字幕日韩欧美一区二区三区| 青青青伊人色综合久久| 欧美a级在线| 色综合久久九月婷婷色综合| 精品久久久久久久久久久久久久久久久| 亚洲视频在线一区| 国产一区二区毛片| 亚洲国产日韩在线| 7777精品伊人久久久大香线蕉的 | 欧美三级蜜桃2在线观看| 国产精品人妖ts系列视频| 久久99久久久欧美国产| 国产精品v亚洲精品v日韩精品|