一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring MVC 處理一個請求的流程

Spring MVC 處理一個請求的流程

2021-08-04 10:59程序員自由之路 Java教程

Spring MVC是Spring系列框架中使用頻率最高的部分。不管是Spring Boot還是傳統的Spring項目,只要是Web項目都會使用到Spring MVC部分。因此程序員一定要熟練掌握MVC部分。本篇博客簡要分析Spring MVC處理一個請求的流程。

一個請求從客戶端發出到達服務器,然后被處理的整個過程其實是非常復雜的。本博客主要介紹請求到達服務器被核心組件DispatcherServlet處理的整理流程(不包括Filter的處理流程)。

1. 處理流程分析

Servlet處理一個請求時會調用service()方法,所以DispatcherServlet處理請求的方式也是從service()方法開始(debug的話建議從DispatcherServlet的service方法開始debug)。FrameworkServlet重寫了HttpServlet的service方法,這個service方法后面又調用了FrameworkServlet的processRequest()方法,processRequest()調用了DispatcherServlet的doService()方法,最后調用到DispatcherServlet的doDispatcher()方法。整合處理請求的方法調用流程如上,下面看下代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
protected void service(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
 
    HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());
    if (HttpMethod.PATCH == httpMethod || httpMethod == null) {
        processRequest(request, response);
    }
    else {
 //這邊調用了HttpServlet的service()方法,但由于FrameWorkServle重寫了doGet、doPost等方法,所以最終還是會調用到processRequest方法
        super.service(request, response);
    }
}

再看看FrameworkServlet的processRequest()方法。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {
 
   long startTime = System.currentTimeMillis();
   Throwable failureCause = null;
 
   LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
   LocaleContext localeContext = buildLocaleContext(request);
 
   RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
   ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);
 
   WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
   asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());
 
   initContextHolders(request, localeContext, requestAttributes);
 
   try {
 //這邊調用DispatcherServlet的doService()方法
       doService(request, response);
   }
   catch (ServletException ex) {
       failureCause = ex;
       throw ex;
   }
   catch (IOException ex) {
       failureCause = ex;
       throw ex;
   }
   catch (Throwable ex) {
       failureCause = ex;
       throw new NestedServletException("Request processing failed", ex);
   }
 
   finally {
       resetContextHolders(request, previousLocaleContext, previousAttributes);
       if (requestAttributes != null) {
           requestAttributes.requestCompleted();
       }
 
       if (logger.isDebugEnabled()) {
           if (failureCause != null) {
               this.logger.debug("Could not complete request", failureCause);
           }
           else {
               if (asyncManager.isConcurrentHandlingStarted()) {
                   logger.debug("Leaving response open for concurrent processing");
               }
               else {
                   this.logger.debug("Successfully completed request");
               }
           }
       }
 
       publishRequestHandledEvent(request, response, startTime, failureCause);
   }
}

doService()方法的具體內容會在后面講到,這邊描述下doDispatcher()的內容,

首先根據請求的路徑找到HandlerMethod(帶有Method反射屬性,也就是對應Controller中的方法),然后匹配路徑對應的攔截器,有了HandlerMethod和攔截器構造個HandlerExecutionChain對象。HandlerExecutionChain對象的獲取是通過HandlerMapping接口提供的方法中得到。有了HandlerExecutionChain之后,通過HandlerAdapter對象進行處理得到ModelAndView對象,HandlerMethod內部handle的時候,使用各種HandlerMethodArgumentResolver實現類處理HandlerMethod的參數,使用各種HandlerMethodReturnValueHandler實現類處理返回值。 最終返回值被處理成ModelAndView對象,這期間發生的異常會被HandlerExceptionResolver接口實現類進行處理。

總結下Spring MVC處理一個請求的過程:

  • 首先,搜索應用的上下文對象 WebApplicationContext 并把它作為一個屬性(attribute)綁定到該請求上,以便控制器和其他組件能夠使用它。
  • 將地區(locale)解析器綁定到請求上,以便其他組件在處理請求(渲染視圖、準備數據等)時可以獲取區域相關的信息。如果你的應用不需要解析區域相關的信息;
  • 將主題(theme)解析器綁定到請求上,以便其他組件(比如視圖等)能夠了解要渲染哪個主題文件。同樣,如果你不需要使用主題相關的特性,忽略它即可如果你配置了multipart文件處理器,那么框架將查找該文件是不是multipart(分為多個部分連續上傳)的。若是,則將該請求包裝成一個 MultipartHttpServletRequest 對象,以便處理鏈中的其他組件對它做進一步的處理。關于Spring對multipart文件傳輸處理的支持;
  • 為該請求查找一個合適的處理器。如果可以找到對應的處理器,則與該處理器關聯的整條執行鏈(前處理器、后處理器、控制器等)都會被執行,以完成相應模型的準備或視圖的渲染如果處理器返回的是一個模型(model),那么框架將渲染相應的視圖。若沒有返回任何模型(可能是因為前后的處理器出于某些原因攔截了請求等,比如,安全問題),則框架不會渲染任何視圖,此時認為對請求的處理可能已經由處理鏈完成了(這個過程就是doService()和doDispatcher()做的事情)

1、 首先用戶發送請求——>DispatcherServlet,前端控制器收到請求后自己不進行處理,而是委托給其他的解析器進行處理,作為統一訪問點,進行全局的流程控制;

2、 DispatcherServlet——>HandlerMapping,HandlerMapping將會把請求映射為HandlerExecutionChain對象(包含一個Handler處理器(頁面控制器)對象、多個HandlerInterceptor攔截器)對象,通過這種策略模式,很容易添加新的映射策略;

3、 DispatcherServlet——>HandlerAdapter,HandlerAdapter將會把處理器包裝為適配器,從而支持多種類型的處理器,即適配器設計模式的應用,從而很容易支持很多類型的處理器;

4、 HandlerAdapter——>處理器功能處理方法的調用,HandlerAdapter將會根據適配的結果調用真正的處理器的功能處理方法,完成功能處理;并返回一個ModelAndView對象(包含模型數據、邏輯視圖名);

5、 ModelAndView的邏輯視圖名——> ViewResolver,ViewResolver將把邏輯視圖名解析為具體的View,通過這種策略模式,很容易更換其他視圖技術;

6、 View——>渲染,View會根據傳進來的Model模型數據進行渲染,此處的Model實際是一個Map數據結構,因此很容易支持其他視圖技術;

7、返回控制權給DispatcherServlet,由DispatcherServlet返回響應給用戶,到此一個流程結束。

2. 請求流程圖

Spring MVC 處理一個請求的流程

還是這個圖比較清楚。發現根據代碼不太能把這個流程說清楚。而且整個流程很長,代碼很多,我就不貼代碼了。這里根據這個圖再把整個流程中組件的功能總結下:

  • DispatcherServlet:核心控制器,所有請求都會先進入DispatcherServlet進行統一分發,是不是感覺有點像外觀模式的感覺;
  • HandlerMapping:這個組件的作用就是將用戶請求的URL映射成一個HandlerExecutionChain。這個HandlerExecutionChain是HandlerMethod和HandlerInterceptor的組合。Spring在啟動的時候會默認注入很多HandlerMapping組件,其中最常用的組件就是RequestMappingHandlerMapping。

上面的HandlerMethod和HandlerInterceptor組件分別對應我們Controller中的方法和攔截器。攔截器會在HandlerMethod方法執行之前執行

  • HandlerAdapter組件,這個組件的主要作用是用來對HandlerMethod中參數的轉換,對方法的執行,以及對返回值的轉換等等。這里面涉及的細節就很多了,包括HandlerMethodArgumentResolver、HandlerMethodReturnValueHandler 、RequestResponseBodyMethodProcessor 、和HttpMessageConvert等組件。

當HandlerAdapter組件執行完成之后會得到一個ModleAndView組件,這個組件代表視圖模型。

  • 得到ModleAndView后會執行攔截器的postHandle方法。
  • 如果在上面的執行過程中發生任何異常,會由HandlerExceptionResolver進行統一處理。
  • 最后模型解析器會對上面的到的ModleAndView進行解析,得到一個一個View返回給客戶端。在返回客戶端之前還會執行攔截器的afterCompletion方法。

以上就是Spring MVC 處理一個請求的流程的詳細內容,更多關于Spring MVC 處理請求的資料請關注服務器之家其它相關文章!

原文鏈接:https://www.cnblogs.com/54chensongxia/p/12525418.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美生活一级片 | 青青草亚洲 | 欧美精品一线二线大片 | 王淑兰李思雨李铁柱乡村小说免费 | 国产在线播放一区 | 香蕉久久久久久狠狠色 | 国产91精品在线观看 | 女教师巨大乳孔中文字幕免费 | 国产成人咱精品视频免费网站 | 亚洲人成网站在线观看90影院 | 果冻传媒天美传媒乌鸦传媒 | 无人知晓小说姜璟免费阅读 | 美女的让男人桶爽30分钟的 | 9久re在线观看视频精品 | 国产精品久久免费 | 成人免费影 | 91私密保健女子养生spa | 我的青梅竹马是消防员2季未增删免费 | 日日碰碰 | 99视频免费 | 欧美高清3dfreexxxx性 | kayden kross喷水 | 国产成人精品免费2021 | 古装一级毛片 | 春宵福利网站在线观看 | 国产日韩精品一区二区在线观看 | 欧美肥胖bb | 嫩模被黑人粗大挺进 | 免费370理论片中文字幕 | 日本亚洲娇小与黑人tube | 精品国产品在线18年 | 亚洲人成网站在线观看妞妞网 | 女人扒开下面让男人桶爽视频 | 国产精品毛片va一区二区三区 | 免费大片 | 3x3x3x短视频在线看 | 久久精品国产在热亚洲 | 超高清欧美同性videos | 免费叼嘿视频 | 三体动漫在线观看免费完整版2022 | 亚洲午夜精品久久久久久人妖 |