本身手寫一個 SpringMVC 框架

前端框架不少,但沒有一個框架稱霸,後端框架如今Spring已經完成大一統.因此學習Spring是Java程序員的必修課.css

Spring 框架對於 Java 後端程序員來講再熟悉不過了,之前只知道它用的反射實現的,但瞭解以後才知道有不少巧妙的設計在裏面。若是不看 Spring 的源碼,你將會失去一次和大師學習的機會:它的代碼規範,設計思想很值得學習。咱們程序員大部分人都是野路子,不懂什麼叫代碼規範。寫了一個月的代碼,最後還得其餘老司機花3天時間重構,相信大部分老司機都很頭疼看新手的代碼。html

廢話很少說,咱們進入今天的正題,在Web應用程序設計中,MVC模式已經被普遍使用。SpringMVC以DispatcherServlet爲核心,負責協調和組織不一樣組件以完成請求處理並返回響應的工做,實現了MVC模式。想要實現本身的SpringMVC框架,須要從如下幾點入手:前端

1、瞭解 SpringMVC 運行流程及九大組件程序員

2、本身實現 SpringMVC 的功能分析web

3、手寫 SpringMVC 框架spring

1、瞭解SpringMVC運行流程及九大組件後端

一、SpringMVC 的運行流程瀏覽器

 

· 用戶發送請求至前端控制器DispatcherServlet前端框架

· DispatcherServlet收到請求調用HandlerMapping處理器映射器。app

· 處理器映射器根據請求url找到具體的處理器,生成處理器對象及處理器攔截器(若是有則生成)一併返回給DispatcherServlet。

· DispatcherServlet經過HandlerAdapter處理器適配器調用處理器

· 執行處理器(Controller,也叫後端控制器)。

· Controller執行完成返回ModelAndView

· HandlerAdapter將controller執行結果● ModelAndView返回給DispatcherServlet

· DispatcherServlet將ModelAndView傳給● ViewReslover視圖解析器

· ViewReslover解析後返回具體View

· DispatcherServlet對View進行渲染視圖(即將模型數據填充至視圖中)。

· DispatcherServlet響應用戶。

從上面能夠看出,DispatcherServlet有接受請求,響應結果,轉發等做用。有了DispatcherServlet以後,能夠減小組件之間的耦合度。

二、SpringMVC 的九大組件

protected void initStrategies(ApplicationContext context) {

//用於處理上傳請求。處理方法是將普通的request包裝成MultipartHttpServletRequest,後者能夠直接調用getFile方法獲取File.

initMultipartResolver(context);

//SpringMVC主要有兩個地方用到了Locale:一是ViewResolver視圖解析的時候;二是用到國際化資源或者主題的時候。

initLocaleResolver(context); 

//用於解析主題。SpringMVC中一個主題對應一個properties文件,裏面存放着跟當前主題相關的全部資源、

//如圖片、css樣式等。SpringMVC的主題也支持國際化, 

initThemeResolver(context);

//用來查找Handler的。

initHandlerMappings(context);

//從名字上看,它就是一個適配器。Servlet須要的處理方法的結構倒是固定的,都是以request和response爲參數的方法。

//如何讓固定的Servlet處理方法調用靈活的Handler來進行處理呢?這就是HandlerAdapter要作的事情

initHandlerAdapters(context);

//其它組件都是用來幹活的。在幹活的過程當中不免會出現問題,出問題後怎麼辦呢?

//這就須要有一個專門的角色對異常狀況進行處理,在SpringMVC中就是HandlerExceptionResolver。

initHandlerExceptionResolvers(context);

//有的Handler處理完後並無設置View也沒有設置ViewName,這時就須要從request獲取ViewName了,

//如何從request中獲取ViewName就是RequestToViewNameTranslator要作的事情了。

initRequestToViewNameTranslator(context);

//ViewResolver用來將String類型的視圖名和Locale解析爲View類型的視圖。

//View是用來渲染頁面的,也就是將程序返回的參數填入模板裏,生成html(也多是其它類型)文件。

initViewResolvers(context);

//用來管理FlashMap的,FlashMap主要用在redirect重定向中傳遞參數。

initFlashMapManager(context); 

}

2、本身實現 SpringMVC 功能分析

本篇文章只實現 SpringMVC 的配置加載、實例化掃描的包、HandlerMapping 的 url 映射到對應的Controller 的 method 上、異常的攔截和動態調用後返回結果輸出給瀏覽器的功能。其他 SpringMVC 功能讀者能夠嘗試本身實現。

一、讀取配置

 

從圖中能夠看出,SpringMVC本質上是一個Servlet,這個 Servlet 繼承自 HttpServlet。

FrameworkServlet負責初始化SpringMVC的容器,並將Spring容器設置爲父容器。由於本文只是實現SpringMVC,對於Spring容器不作過多講解(有興趣同窗能夠看看博主另外一篇文章:向spring大佬低頭--大量源碼流出解析)。

爲了讀取web.xml中的配置,咱們用到ServletConfig這個類,它表明當前Servlet在web.xml中的配置信息。經過web.xml中加載咱們本身寫的MyDispatcherServlet和讀取配置文件。

二、初始化階段

在上文中,咱們知道了DispatcherServlet的initStrategies方法會初始化9大組件,可是本文將實現一些SpringMVC的最基本的組件而不是所有,按順序包括:

· 加載配置文件

· 掃描用戶配置包下面全部的類

· 拿到掃描到的類,經過反射機制,實例化。而且放到ioc容器中(Map的鍵值對  beanName-bean) beanName默認是首字母小寫

· 初始化HandlerMapping,這裏其實就是把url和method對應起來放在一個k-v的Map中,在運行階段取出

三、運行階段

每一次請求將會調用doGet或doPost方法,因此統一運行階段都放在doDispatch方法裏處理,它會根據url請求去HandlerMapping中匹配到對應的Method,而後利用反射機制調用Controller中的url對應的方法,並獲得結果返回。按順序包括如下功能:

· 異常的攔截

· 獲取請求傳入的參數並處理參數

· 經過初始化好的handlerMapping中拿出url對應的方法名,反射調用

3、手寫 SpringMVC 框架

工程文件及目錄:

 

首先,新建一個maven項目,在pom.xml中導入如下依賴。爲了方便,博主直接導入了Springboot的web包,裏面有咱們須要的全部web開發的東西:

 

接着,咱們在WEB-INF下建立一個web.xml,以下配置:

 

application.properties文件中只是配置要掃描的包到SpringMVC容器中。

scanPackage=com.liugh.core

建立本身的Controller註解,它只能標註在類上面:

 

RequestMapping註解,能夠在類和方法上:

 

RequestParam註解,只能註解在參數上

 

而後建立MyDispatcherServlet這個類,去繼承HttpServlet,重寫init方法、doGet、doPost方法,以及加上咱們第二步分析時要實現的功能:

 

 

 

 

 

 

這裏咱們就開發完了本身的SpringMVC,如今咱們測試一下:

 

訪問http://localhost:8080/liughMVC/test/doTest?param=liugh以下:

 

訪問一個不存在的試試:

 

到這裏咱們就大功告成了!

相關文章
相關標籤/搜索