中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringMVC的源碼解析

發布時間:2020-10-21 08:24:16 來源:腳本之家 閱讀:145 作者:xjz1842 欄目:編程語言

學習java的人都知道spring,springMVC,mybatis等框架,像structs2這樣的框架是基于servlet以外實現的,而springMVC是基于servlet容器實現的,

本文將分析SpringMVC的核心分發器DispatcherServlet的初始化過程以及處理請求的過程,讓讀者了解這個入口Servlet的作用。

在分析DispatcherServlet之前,我們先看下DispatcherServlet的繼承關系,

SpringMVC的源碼解析

HttpSerlvetBean繼承自HttpServlet。

HttpServletBean覆寫了init方法,對初始化過程做了一些處理。 以下是初始化的代碼:

SpringMVC的源碼解析

首先,ServletConfigPropertyValues是HttpServletBean的靜態類,構造過程會使用ServletConfig對象找出web.xml文件中配置參數,并設置到ServletConfigPropertyValue,使用BeanWrapper來構造DispatcherServlet, 獲取ServletContextResourceLoader的資源加載器,然后注冊資源編輯器,初始化BeanWrapper對象,設置DispatcherServlet屬性,默認初始化ServletBean不做任何處理,子類覆蓋該方法可以做任何事情,

以下是web.xml文件配置:

SpringMVC的源碼解析

這段配置初始化參數為contextConfigLocation,后來構造的是BeanWrapper對象, 由于contextConfigLocation在FrameworkServlet中定義,但是沒有在HttpServletBean中定義,利用Spring的注入特性,只需要調用setContextConfigLocation方法,就可以將contextConfigLocation設置到對應的實例當中,然后設置DispatcherServlet中contextConfigLocation(FrameworkServlet中定義)的屬性,為web.xml讀取contextConfigLocation參數,該資源文件用構造SpringMVC的容器的上下文。

下面看下FrameworkServlet這個類,FrameworkServlet繼承自HttpServletBean。

以下是initServletBean的代碼:

SpringMVC的源碼解析

首先第一步是初始化WebApplicationContext,它是繼承于ApplcationContext的接口,ApplcationContext是Spring容器的上下文,Servlet和Spring容器關聯的作用,然后初始化FrameWorkServlet,其實它空的,什么也做,子類重寫這個方法,可以做任何處理,不過DispatcherServlet并重寫這個方法。

下面是初始化initWebApplicationContext的具體實現邏輯: 

SpringMVC的源碼解析    

首先,得到根路徑,DistpatcherServlet有個WebApplication為參數的構造函數,如果注入了WebApplication 這個對象,就會執行上圖代碼。

SpringMVC的源碼解析

FrameworkServlet中有個String類型的contextAttribute的變量名,以它為key在ServletContextWebApplicationContext,一般不會設置,contextAttribute屬性,也就說,wac開始是null;接下來就是創建WebApplicationContext,并設置根上下文為父上下文,然后配置ServletConfig,ServletContext等到這個上下文,這個類中有個函數onReFresh是一個模版方法,在WebApplication成功創建后就會調用,FrameworkServlet的實現類,就會重寫這個方法,并將創建的容器上下文設置到ServletContext中,這里的根上下文是web.xml中配置的ContextLoaderListener監聽器中根據contextConfigLocation路徑生成的上下文。

SpringMVC的源碼解析

比如這段配置文件中根據classpath:context-*.xml下的xml文件生成的根上下文。

接著看一下DispatcherServlet重寫了FrameworkServlet中onReFresh方法,

SpringMVC的源碼解析

可以看到initStrategies方法中,在初始化各種各種策略接口的實現類, 后面再一一分析各個策略接口的實現的詳細介紹。

總結一個三個類的作用:

HttpServletBean 主要做一些初始化的工作,將web.xml中配置的參數設置到Servlet中。比如servlet標簽的子標簽init-param標簽中配置的參數。

FrameworkServlet 將Servlet與Spring容器上下文關聯。其實也就是初始化FrameworkServlet的屬性webApplicationContext,這個屬性代表SpringMVC上下文,它有個父類上下文,web.xml中配置的ContextLoaderListener監聽器初始化的容器上下文。

DispatcherServlet 主要是初始化一些各個策略接口的實現。比如請求處理,試圖處理。處理的適配等。

DispatcherServlet請求處理過程:

先看下HttpServlet提供的方法用于處理請求,service使用了模版模式,對于HttpServlet的get請求,調用doGet方法,post請 求,調用doPost方法........

SpringMVC的源碼解析

在看下處理processRequest函數

SpringMVC的源碼解析

首先,獲取于當前線程綁定的LocaleContext和ServletRequestAttributes對象,initContextHoers函數就是讓新構造的LocaleContex和requestAttributes進行關聯,這個關聯使用ThreadLocal完成,doService方法是抽象方法,具體由DispatcherServlet實現。

SpringMVC的源碼解析

最后調用resetContextHolders函數重置LocaleContext和RequestAttribute對象,解除LocaleContext和RequestAttribute對象的綁定。執行成功后,發布ServletRequestHandlerEvent事件,可以通過注冊監聽器來監聽該事件的發布。注冊的監聽器類型為ApplicationListener接口類型。

接下來是DispatcherServlet的doService方法.

SpringMVC的源碼解析

如果該請求是include的請求,那么保留一份快照版本的request域中的數據,doDispatch方法之后,這個快照版本的數據將會覆蓋新的Requet域的數據。  

然后在request中設置一些屬性,最后doDispatcher進行請求分發處理。      

doDispatch方法功能大致過程如下:

首先根據請求的路徑,通過RequestMapping的注解映射,找到HandlerMethod(也就是對應Controller中的方法),然后匹配路徑對應的攔截器,有了HandlerMethod和攔截器構造個HandlerExecutionChain對象。HandlerExecutionChain對象的獲取是通過HandlerMapping接口提供的方法中得到。

有了HandlerExecutionChain之后,通過handlerAdapter對象進行適配處理,得到ModelAndView對象,HandlerMethod內部handle的時候,使用各種HandlerMethodArgumentResolver實現類處理HandlerMethod的參數,使用各種HandlerMethodReturnValueHandler實現類處理返回值,最終返回值被處理成一個ModelAndView對象,這期間發生的異常會被HandlerExceptionResolver接口實現類進行處理.

總結: 本文主要分析DispatcherServlet及其父類FrameworkServlet和HttpServletBean它們的作用。以及一個請求到處理返回,大致過程的分析。

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持億速云!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

荥经县| 石狮市| 卫辉市| 砀山县| 阳西县| 康定县| 布尔津县| 汶川县| 新泰市| 隆尧县| 察哈| 桐柏县| 高碑店市| 南京市| 沁水县| 长岛县| 衡水市| 濮阳县| 荥经县| 西昌市| 河池市| 杂多县| 元谋县| 扶绥县| 黄平县| 利津县| 都昌县| 新昌县| 武川县| 营山县| 英吉沙县| 滦南县| 绥德县| 翼城县| 九寨沟县| 南澳县| 鄂托克旗| 雅江县| 水富县| 紫金县| 波密县|