您好,登錄后才能下訂單哦!
學習java的人都知道spring,springMVC,mybatis等框架,像structs2這樣的框架是基于servlet以外實現的,而springMVC是基于servlet容器實現的,
本文將分析SpringMVC的核心分發器DispatcherServlet的初始化過程以及處理請求的過程,讓讀者了解這個入口Servlet的作用。
在分析DispatcherServlet之前,我們先看下DispatcherServlet的繼承關系,
HttpSerlvetBean繼承自HttpServlet。
HttpServletBean覆寫了init方法,對初始化過程做了一些處理。 以下是初始化的代碼:
首先,ServletConfigPropertyValues是HttpServletBean的靜態類,構造過程會使用ServletConfig對象找出web.xml文件中配置參數,并設置到ServletConfigPropertyValue,使用BeanWrapper來構造DispatcherServlet, 獲取ServletContextResourceLoader的資源加載器,然后注冊資源編輯器,初始化BeanWrapper對象,設置DispatcherServlet屬性,默認初始化ServletBean不做任何處理,子類覆蓋該方法可以做任何事情,
以下是web.xml文件配置:
這段配置初始化參數為contextConfigLocation,后來構造的是BeanWrapper對象, 由于contextConfigLocation在FrameworkServlet中定義,但是沒有在HttpServletBean中定義,利用Spring的注入特性,只需要調用setContextConfigLocation方法,就可以將contextConfigLocation設置到對應的實例當中,然后設置DispatcherServlet中contextConfigLocation(FrameworkServlet中定義)的屬性,為web.xml讀取contextConfigLocation參數,該資源文件用構造SpringMVC的容器的上下文。
下面看下FrameworkServlet這個類,FrameworkServlet繼承自HttpServletBean。
以下是initServletBean的代碼:
首先第一步是初始化WebApplicationContext,它是繼承于ApplcationContext的接口,ApplcationContext是Spring容器的上下文,Servlet和Spring容器關聯的作用,然后初始化FrameWorkServlet,其實它空的,什么也做,子類重寫這個方法,可以做任何處理,不過DispatcherServlet并重寫這個方法。
下面是初始化initWebApplicationContext的具體實現邏輯:
首先,得到根路徑,DistpatcherServlet有個WebApplication為參數的構造函數,如果注入了WebApplication 這個對象,就會執行上圖代碼。
FrameworkServlet中有個String類型的contextAttribute的變量名,以它為key在ServletContextWebApplicationContext,一般不會設置,contextAttribute屬性,也就說,wac開始是null;接下來就是創建WebApplicationContext,并設置根上下文為父上下文,然后配置ServletConfig,ServletContext等到這個上下文,這個類中有個函數onReFresh是一個模版方法,在WebApplication成功創建后就會調用,FrameworkServlet的實現類,就會重寫這個方法,并將創建的容器上下文設置到ServletContext中,這里的根上下文是web.xml中配置的ContextLoaderListener監聽器中根據contextConfigLocation路徑生成的上下文。
比如這段配置文件中根據classpath:context-*.xml下的xml文件生成的根上下文。
接著看一下DispatcherServlet重寫了FrameworkServlet中onReFresh方法,
可以看到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方法........
在看下處理processRequest函數
首先,獲取于當前線程綁定的LocaleContext和ServletRequestAttributes對象,initContextHoers函數就是讓新構造的LocaleContex和requestAttributes進行關聯,這個關聯使用ThreadLocal完成,doService方法是抽象方法,具體由DispatcherServlet實現。
最后調用resetContextHolders函數重置LocaleContext和RequestAttribute對象,解除LocaleContext和RequestAttribute對象的綁定。執行成功后,發布ServletRequestHandlerEvent事件,可以通過注冊監聽器來監聽該事件的發布。注冊的監聽器類型為ApplicationListener接口類型。
接下來是DispatcherServlet的doService方法.
如果該請求是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它們的作用。以及一個請求到處理返回,大致過程的分析。
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持億速云!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。