第三十六章 Spring之假如讓你來寫MVC——攔截器篇

Spring源碼閱讀目錄

第一部分——IOC篇

第一章 Spring之最熟悉的陌生人——IOC
第二章 Spring之假如讓你來寫IOC容器——加載資源篇
第三章 Spring之假如讓你來寫IOC容器——解析配置文件篇
第四章 Spring之假如讓你來寫IOC容器——XML配置文件篇
第五章 Spring之假如讓你來寫IOC容器——BeanFactory和FactoryBean
第六章 Spring之假如讓你來寫IOC容器——Scope和屬性填充
第七章 Spring之假如讓你來寫IOC容器——屬性填充特別篇:SpEL表達式
第八章 Spring之假如讓你來寫IOC容器——拓展篇
第九章 Spring之源碼閱讀——環境搭建篇
第十章 Spring之源碼閱讀——IOC篇

第二部分——AOP篇

第十一章 Spring之不太熟的熟人——AOP
第十二章 Spring之不得不了解的內容——概念篇
第十三章 Spring之假如讓你來寫AOP——AOP聯盟篇
第十四章 Spring之假如讓你來寫AOP——雛形篇
第十五章 Spring之假如讓你來寫AOP——Joinpoint(連接點)篇
第十六章 Spring之假如讓你來寫AOP——Pointcut(切點)篇
第十七章 Spring之假如讓你來寫AOP——Advice(通知)上篇
第十八章 Spring之假如讓你來寫AOP——Advice(通知)下篇
第十九章 Spring之假如讓你來寫AOP——番外篇:Spring早期設計
第二十章 Spring之假如讓你來寫AOP——Aspect(切面)篇
第二十一章 Spring之假如讓你來寫AOP——Weaver(織入器)篇
第二十二章 Spring之假如讓你來寫AOP——Target Object(目標對象)篇
第二十三章 Spring之假如讓你來寫AOP——融入IOC容器篇
第二十四章 Spring之源碼閱讀——AOP篇

第三部分——事務篇

第二十五章 Spring之曾經的老朋友——事務
第二十六章 Spring之假如讓你來寫事務——初稿篇
第二十七章 Spring之假如讓你來寫事務——鐵三角篇
第二十八章 Spring之假如讓你來寫事務——屬性篇
第二十九章 Spring之假如讓你來寫事務——狀態篇
第三十章 Spring之假如讓你來寫事務——管理篇
第三十一章 Spring之假如讓你來寫事務——融入IOC容器篇
第三十二章 Spring之源碼閱讀——事務篇

第四部分——MVC篇

第三十三章 Spring之夢開始的地方——MVC
第三十四章 Spring之假如讓你來寫MVC——草圖篇
第三十五章 Spring之假如讓你來寫MVC——映射器篇
第三十六章 Spring之假如讓你來寫MVC——攔截器篇
第三十七章 Spring之假如讓你來寫MVC——控制器篇
第三十八章 Spring之假如讓你來寫MVC——適配器篇
第三十九章 Spring之假如讓你來寫MVC——番外篇:類型轉換
第四十章 Spring之假如讓你來寫MVC——ModelAndView篇
第四十一章 Spring之假如讓你來寫MVC——番外篇:數據綁定
第四十二章 Spring之假如讓你來寫MVC——視圖篇
第四十三章 Spring之假如讓你來寫MVC——上傳文件篇
第四十四章 Spring之假如讓你來寫MVC——異常處理器篇
第四十五章 Spring之假如讓你來寫MVC——國際化篇
第四十六章 Spring之假如讓你來寫MVC——主題解析器篇
第四十七章 Spring之假如讓你來寫MVC——閃存管理器篇
第四十八章 Spring之假如讓你來寫MVC——請求映射視圖篇
第四十九章 Spring之假如讓你來寫MVC——番外篇:屬性操作
第五十章 Spring之假如讓你來寫MVC——融入IOC容器篇
第五十一章 Spring之源碼閱讀——MVC篇


文章目錄

  • Spring源碼閱讀目錄
    • 第一部分——IOC篇
    • 第二部分——AOP篇
    • 第三部分——事務篇
    • 第四部分——MVC篇
  • 前言
  • 嘗試動手寫IOC容器
      • 第三十二版 攔截器
        • 攔截器接口
        • 改造映射器
        • 改造`DispatcherServlet`
        • 測試
  • 總結


前言

????對于Spring一直都是既熟悉又陌生,說對它熟悉吧,平時用用沒啥問題,但面試的時候被問的一臉懵逼,就很尷尬,都不好意思在簡歷上寫著熟悉Spring了
在這里插入圖片描述

????所以決定花點時間研究研究Spring的源碼。主要參考的書籍是:《Spring源碼深度解析(第2版)》、《Spring揭秘》、《Spring技術內幕:深入解析Spring架構與設計原理(第2版)》


???? 書接上回,在上篇 第三十五章 Spring之假如讓你來寫MVC——映射器篇 中,A君 已經實現了 映射器 部分的功能了。接下來看看 A君 會有什么騷操作吧

嘗試動手寫IOC容器

????出場人物:A君(苦逼的開發)、老大(項目經理)

????背景:老大 要求 A君在一周內開發個簡單的 IOC容器

????前情提要:A君 已經實現了 映射器 部分的功能了 。。。

第三十二版 攔截器

????今天,剛一上班,A君 就屁顛屁顛的跑到 老大 的辦公室去,炫耀自己的成果

????“嗯。做的不錯。不過還需要加點料?” 老大 看著滿臉興奮的 A君 。悠悠說道

????“加點料,要加什么??” A君 興奮地逐漸消失,一臉懵逼的問到

????“你聽說過 過濾器 嗎?” 老大 微笑著問道

????“聽說過,過濾器Servlet 規范中的一部分,所有 Servlet容器 都必須實現。請求在到達 Servlet 之前,或者響應返回客戶端之前,都會經過 過濾器 進行處理。如果 過濾器 處理不通過,它可以阻止請求繼續往下處理!” A君 回答道

????“不錯,現在要加的料和 過濾器 效果差不多,只是是框架層面的。叫做 攔截器。” 老大 說到

????“為什么有 過濾器 之后還需要 攔截器 呢?” A君 提出疑問

????“問得好!原因其實也很簡單。過濾器Servlet容器 的行為,發生在 Servlet 之前,那么就以為這它無法獲取框架中的內容,無法進行更細致的攔截。” 老大 笑著說道

????“原來如此!” A君 恍然,之前一直存在的疑問,被 老大 三言兩語就解開了

????“去吧!這東西并不難,我希望今天就能看到成果!” 老大 大手一揮,開始下逐客令

攔截器接口

????“OK!” A君 也爽快的回答道,離開辦公室,回到自己的工位上。A君 想都沒想,就開始擼代碼,因為像這種提供拓展的功能,A君 只需要提供接口就行,具體內容由用戶實現即可。A君 新增 HandlerInterceptor接口,代碼如下:

/*** 攔截器接口*/
public interface HandlerInterceptor {/*** 方法執行前調用** @param request* @param response* @param handler* @return* @throws Exception*/default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {return true;}/*** 方法執行后調用** @param request* @param response* @param handler* @throws Exception*/default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {}/*** 請求完成時調用,不管成功還是失敗** @param request* @param response* @param handler* @param ex* @throws Exception*/default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}

好了,接口定義了完成了。不過要如何執行它的實現呢?老大 之前提到和 過濾器 類似,說起 過濾器A君 其實并不算陌生,之前有折騰過 Tomcat,知道其大致的運行流程。這里又得涉及到一個設計模式——責任鏈。這個模式也好理解,就像 A君 平時想請個假,OA上需要經過層層審批,層層回復一樣:

請假
同意
同意
同意
回復
回復
回復
回復
A君
項目經理
部門經理
技術總監
結束

每一層都得同意,這個假才算請成功,但凡有一個不同意,這個假就算是請失敗了。值得注意的是:請假流程申請的時候是從前往后,而回復的時候卻是從后往前的責任鏈 與之類似,既然如此,那么 攔截器 也就好辦了:只要把 攔截器 整合成一個鏈表就可以了。A君 添加HandlerExecutionChain類,代碼如下:

/*** 請求處理鏈*/
@Getter
public class HandlerExecutionChain {/*** 控制器*/private final Object handler;/*** 攔截器集合*/private final List<HandlerInterceptor> interceptorList = new ArrayList<>();private int interceptorIndex = -1;/*** 正向處理,類似與請假申請流程** @param request* @param response* @return* @throws Exception*/boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {for (int i = 0; i < this.interceptorList.size(); i++) {HandlerInterceptor interceptor = this.interceptorList.get(i);if (!interceptor.preHandle(request, response, this.handler)) {//返回false,直接調用完成方法triggerAfterCompletion(request, response, null);return false;}this.interceptorIndex = i;}return true;}/*** 反向處理,類似與請假回復流程** @param request* @param response* @throws Exception*/void applyPostHandle(HttpServletRequest request, HttpServletResponse response)throws Exception {for (int i = this.interceptorList.size() - 1; i >= 0; i--) {HandlerInterceptor interceptor = this.interceptorList.get(i);interceptor.postHandle(request, response, this.handler);}}/*** 反向處理,類似與請假回復流程** @param request* @param response* @throws Exception*/void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) {for (int i = this.interceptorIndex; i >= 0; i--) {HandlerInterceptor interceptor = this.interceptorList.get(i);try {interceptor.afterCompletion(request, response, this.handler, ex);} catch (Throwable ex2) {ex2.printStackTrace();}}}//其他方法省略
}
改造映射器

確實如 老大 所說,攔截器 就這么點東西,沒啥難度的。現在還需要改下 映射器 的返回值了,之前是直接返回HandlerMethod,現在得返回HandlerExecutionChain了,改動如下:

在這里插入圖片描述
AbstractHandlerMapping也做個簡單的改動,需要把配置的 攔截器 添加到HandlerExecutionChain中,如下:

在這里插入圖片描述

改造DispatcherServlet

現在基本改造完了,還需要個添加 攔截器 的入口,只需要掃描類是否實現了對應接口就行了。DispatcherServlet改動如下:

在這里插入圖片描述

測試

????好嘞,現在一切都準備就緒了。可以開始準備測試了,其他內容還是不需要改動。只需要新增一個 攔截器 即可,A君 新增MyInterceptor。代碼如下:

public class MyInterceptor implements HandlerInterceptor {// 在請求處理前執行@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("Pre-handle: " + request.getRequestURI());request.setAttribute("message", "Add Interceptor");return true;}// 在請求處理后,視圖渲染前執行@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("Post-handle: " + request.getRequestURI());}// 在請求完全處理完后執行@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,Exception ex) throws Exception {System.out.println("After completion: " + request.getRequestURI());}
}

添加測試代碼如下:

	 @Testpublic void v32() throws Throwable {System.out.println("############# 第三十二版: 攔截器篇 #############");Tomcat tomcat = new Tomcat();//設置端口tomcat.setPort(8082);//設置靜態資源路徑String webApp = new File("src/main/resources/v32").getAbsolutePath();tomcat.addWebapp("/test/", webApp);tomcat.start();//掛起tomcat.getServer().await();}

測試結果如下:

在這里插入圖片描述

在這里插入圖片描述

前臺成功返回,后臺也成功打印。攔截器 也就這么完成啦。OK!起碼今天可以交差了,看看 老大 明天還有什么想法吧

在這里插入圖片描述


總結

????正所謂樹欲靜而風不止,欲知后事如何,請看下回分解(?ω?)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/65930.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/65930.shtml
英文地址,請注明出處:http://en.pswp.cn/web/65930.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

快速上手 HarmonyOS 應用開發

一、DevEco Studio 安裝與配置 1. DevEco Studio 簡介 DevEco Studio 是 HarmonyOS 的一站式集成開發環境&#xff08;IDE&#xff09;&#xff0c;提供了豐富的工具和功能&#xff0c;支持 HarmonyOS 應用開發的全流程。 2. DevEco Studio 下載與安裝 下載地址&#xff1a…

Java Web開發進階——錯誤處理與日志管理

錯誤處理和日志管理是任何生產環境中不可或缺的一部分。在 Spring Boot 中&#xff0c;合理的錯誤處理機制不僅能夠提升用戶體驗&#xff0c;還能幫助開發者快速定位問題&#xff1b;而有效的日志管理能夠幫助團隊監控應用運行狀態&#xff0c;及時發現和解決問題。 1. 常見錯誤…

圖解Git——分支的新建與合并《Pro Git》

?分支的新建與合并 先引入一個實際開發的工作流&#xff1a; 開發某個網站。為實現某個新的需求&#xff0c;創建一個分支。在這個分支上開展工作。 正在此時&#xff0c;你突然接到一個電話說有個很嚴重的問題需要緊急修補。你將按照如下方式來處理&#xff1a; 切換到你…

C#使用實體類Entity Framework Core操作mysql入門:從數據庫反向生成模型2 處理連接字符串

初級代碼游戲的專欄介紹與文章目錄-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代碼都將會位于ctfc庫中。已經放入庫中我會指出在庫中的位置。 這些代碼大部分以Linux為目標但部分代碼是純C的&#xff0c;可以在任何平臺上使用。 源碼指引&#xff1a;github源…

【數據可視化-12】數據分析崗位招聘分析

&#x1f9d1; 博主簡介&#xff1a;曾任某智慧城市類企業算法總監&#xff0c;目前在美國市場的物流公司從事高級算法工程師一職&#xff0c;深耕人工智能領域&#xff0c;精通python數據挖掘、可視化、機器學習等&#xff0c;發表過AI相關的專利并多次在AI類比賽中獲獎。CSDN…

LeetCode 977 題:有序數組的平方

LeetCode 977 題&#xff1a;有序數組的平方 (Squares of a Sorted Array) LeetCode 第977題要求給定一個按非降序排列的整數數組 nums&#xff0c;返回每個數字的平方并按升序排列。 題目描述 給定一個整數數組 nums&#xff0c;它按非降序排列&#xff08;即 nums[i] < …

excel僅復制可見單元格,僅復制篩選后內容

背景 我們經常需要將內容分給不同的人&#xff0c;做完后需要合并 遇到情況如下 那是因為直接選擇了整列&#xff0c;當然不可以了。 下面提供幾種方法&#xff0c;應該都可以 直接選中要復制區域然后復制&#xff0c;不要選中最上面的列alt;選中可見單元格正常復制&#xff…

微信小程序實現拖拽盒子效果

要實現一個當前盒子高度由里面的盒子進行支配高度拖拽的效果 // wxml<view class"exmation-item" wx:elif"{{type4}}"> <view class"exmation-item-drag-box" id"drag-box"> <!-- 內容 --><view class"exm…

支持向量回歸(SVR:Support Vector Regression)用于A股數據分析、預測

簡單說明 支持向量回歸是一種用來做預測的數學方法,屬于「機器學習」的一種。 它的目標是找到一條「最合適的線」,能夠大致描述數據點的趨勢,并允許數據點離這條線有一定的誤差(不要求所有點都完全落在這條線上)。 可以把它想象成:找到一條「寬帶」或「隧道」,大部分…

透明部署、旁路邏輯串聯的區別

背景 需討論防火墻到底是串聯&#xff0c;還是旁掛。 通常串聯指的就是“透明部署”&#xff0c;旁掛指的就是“邏輯串聯”。 透明部署&#xff08;串聯&#xff09; 也稱為透明模式或橋接模式&#xff0c;是一種安全設備的部署方式。在這種模式下&#xff0c;安全設備被串聯…

LabVIEW水位監控系統

LabVIEW開發智能水位監控系統通過集成先進的傳感技術與控制算法&#xff0c;為工業液體存儲提供精確的水位調控&#xff0c;保證了生產過程的連續性與安全性。 項目背景 在化工和飲料生產等行業中&#xff0c;水位控制的準確性對保證生產安全和提高產品質量至關重要。傳統的水…

深入淺出 Android AES 加密解密:從理論到實戰

深入淺出 Android AES 加密解密&#xff1a;從理論到實戰 在現代移動應用中&#xff0c;數據安全是不可忽視的一環。無論是用戶隱私保護&#xff0c;還是敏感信息的存儲與傳輸&#xff0c;加密技術都扮演著重要角色。本文將以 AES&#xff08;Advanced Encryption Standard&am…

hadoop-yarn常用命令

一、YARN命令介紹 1. YARN命令簡介 YARN提供了一組命令行工具&#xff0c;用于管理和監控YARN應用程序和集群。 2. yarn application命令 (1) yarn application命令的基本語法 yarn application命令的基本語法如下&#xff1a; yarn application [genericOptions] [comma…

R語言的語法糖

R語言的語法糖 引言 在編程語言中&#xff0c;所謂的“語法糖”是指那些使得程序員能夠以更簡潔、直觀的方式書寫代碼的語法形式。R語言作為一種用于統計分析和數據可視化的編程語言&#xff0c;具有豐富的功能和靈活的語法。本文將深入探討R語言中的語法糖&#xff0c;幫助讀…

React Fiber框架中的Render渲染階段——workLoop(performUnitOfWork【beginWork與completeWork】)

觸發渲染過程——renderRoot renderRoot 是一個函數&#xff0c;用于觸發渲染工作。它通常會調用并遞歸地執行一系列的渲染任務&#xff0c;直到完成整個更新過程。這個過程包括執行 Fiber 樹中的 beginWork 和 completeWork&#xff0c;以及渲染新狀態或 DOM。 function ren…

【優先算法】思還故里閭,欲歸道無因 - 前綴和

本篇博客給大家帶來的是前綴和算法的知識點, 也是一樣通過OJ題理解,掌握,應用該算法. &#x1f40e;文章專欄: 算法 &#x1f680;若有問題 評論區見 ? 歡迎大家點贊 評論 收藏 分享 如果你不知道分享給誰,那就分享給薯條. 你們的支持是我不斷創作的動力 . 王子,公主請閱&…

億道三防丨三防筆記本是什么意思?和普通筆記本的優勢在哪里?

三防筆記本是什么意思&#xff1f;和普通筆記本的優勢在哪里&#xff1f; 在現代社會中&#xff0c;筆記本電腦已經成為人們工作和生活中不可或缺的一部分。然而&#xff0c;在一些特殊行業或環境中&#xff0c;普通筆記本電腦由于其脆弱性和對環境條件的敏感性&#xff0c;往…

SOME/IP 協議詳解——服務發現

文章目錄 1. Introduction &#xff08;引言&#xff09;2. SOME/IP Service Discovery (SOME/IP-SD)2.1 General&#xff08;概述)2.2 SOME/IP-SD Message Format2.2.1 通用要求2.2.2 SOME/IP-SD Header2.2.3 Entry Format2.2.4 Options Format2.2.4.1 配置選項&#xff08;Co…

MATLAB語言的函數實現

MATLAB語言中的函數實現詳解 引言 MATLAB&#xff08;矩陣實驗室&#xff09;是一種高級語言和互動環境&#xff0c;廣泛應用于數值計算、數據分析、可視化以及工程與科學計算等多個領域。MATLAB的強大之處在于其豐富的函數庫以及用戶自定義函數的能力。本文將深入探討MATLAB…

Go語言之路————go環境的初始化

Go語言之路————go環境的初始化 前言一、Go的安裝二、環境配置三、初始化一個新項目四、常用的一些指令 前言 我是一名多年Java開發人員&#xff0c;因為工作需要現在要學習go語言&#xff0c;Go語言之路是一個系列&#xff0c;記錄著我從0開始接觸Go&#xff0c;到后面能正…