spring源碼解析-web系列(一):啓動
spring源碼解析-web系列(二):處理請求的過程
spring源碼解析-web系列(三):九大組件之HandlerMapping
spring源碼解析-web系列(四):九大組件之HandlerAdapter
spring源碼解析-web系列(五):解析請求參數
spring源碼解析-web系列(六):九大組件之ViewResolver
spring源碼解析-web系列(七):九大組件之HandlerExceptionResolver
轉載請標明出處:
https://blog.csdn.net/bingospunky/article/details/97640326
本文出自馬彬彬的博客
servlet
在j2ee規範裏,處理請求的就是servlet,我們使用spring時,配置的就是DispatcherServlet來處理。當請求來到以後,被DispatcherServlet處理,在DispatcherServle中,找到我們配置的controller、解析參數、處理返回值等。
DispatcherServlet的繼承關係也比較簡答,DispatcherServlet -> FrameworkServlet -> HttpServletBean。
HttpServletBean
HttpServletBean類很簡單,繼承HttpServlet,添加了一些對spring環境的支持。
FrameworkServlet
FrameworkServlet裏的service、doGet、doPost等一些其他方法都會調用FrameworkServlet.processRequest來處理。在processRequest中,先處理LocaleContext和ServletRequestAttributes和當前線程的關係,然後調用doService方法處理邏輯,最後調用publishRequestHandledEvent方法發送ServletRequestHandledEvent事件。
doService方法被DispatcherServlet覆蓋,處理具體邏輯。
DispatcherServlet
1.doService方法也沒有直接處理,而是交給了doDispatch,該方法先做了一些準備工作,比如把WebApplicationContext、localeResolver、themeResolver等對象存放到request的Attribute裏,以便後續方便使用。
2.doDispatch的流程如下:
圖1:
這裏注意doDispatch的兩層Exception處理,內層是捕獲對請求吹過程中的異常,外層是渲染時拋出的異常。
對於內層的異常處理,如果存在合適的HandlerExceptionResolver(@ExceptionHandler註解的方法),則使用HandlerExceptionResolver進行處理,如果沒有合適的HandlerExceptionResolver進行處理,則往外拋異常。
對於外層的異常,捕獲該異常,做一些相關操作或者new一個新的異常,然後再拋出來,該異常不會被消化掉的,直到拋出到Servlet裏,由Tomcat容器來處理。
總結
借用《看透spring mvc源代碼分析與實踐》裏的總結來總結。
圖2: