1. 程式人生 > >SpringMVC原始碼剖析(二)- DispatcherServlet的前世今生

SpringMVC原始碼剖析(二)- DispatcherServlet的前世今生

上一篇文章《SpringMVC原始碼剖析(一)- 從抽象和介面說起》中,我介紹了一次典型的SpringMVC請求處理過程中,相繼粉墨登場的各種核心類和介面。我刻意忽略了原始碼中的處理細節,只列出最簡單的類甚至是介面類,目的就是讓大家先從最高層次的抽象意義上來審視SpringMVC這個框架;我也刻意將SpringMVC和Struts2做對比,目的是讓大家看到,SpringMVC究竟吸取了Sturts2設計思想中的哪些精華,又彌補了它的哪些遺憾。

DispatcherServlet作為SpringMVC的核心之中的核心類,再怎麼強調它的重要性也不為過。SpringMVC所有的核心類和介面,都密集地出現在DispatcherServlet的原始碼中,SpringMVC原始碼剖析,很大程度上可以說也是在剖析DispatcherServlet這一個類。這一篇文章裡,我先說幾點關於DispatcherServlet的前世今生,希望能幫助你更好的理解它。

1.對擴充套件開放,對修改封閉

SpringMVC是一個基於著名的Open-Closed,即開閉原則進行設計的框架。在Spring官方文件裡面關於SpringMVC的介紹開宗明義地進行了說明:

1 A key design principle in Spring Web MVC and in Spring in general is the “Open for extension,closed for modification” principle.

開閉原則是一個很寬泛的原則,具體體現到DispatcherServlet的原始碼中,我們可以大致摸得到一些線索:

  • 類中所有的變數宣告,幾乎都以介面的形式給出,並沒有繫結在具體的實現類上。
  • 使用模版方法模式,在父類中對基礎行為進行定義,讓子類實現模版方法擴充套件行為。

其中第一點,在一個框架的設計中尤為重要,也是貫徹開閉原則最重要的一點。因為當你通過一些高層次的介面或者抽象類,將一個類完成的邏輯或流程編寫完成後(具體點說,是通過一個介面的引用呼叫介面方法),整個邏輯或流程的功能就被確實的在原始碼中固定下來了。可是這時,這些介面或抽象類的具體實現者是誰,還沒有固定!這就給了你的系統或框架近乎無限的擴充套件性,因為你可以任意安排和實現這些類。

我認為,面向物件設計的精髓,是對現實世界中“行為和契約”的描述。這個“行為和契約”,體現在介面和抽象類的方法宣告中。軟體設計師要用面向物件的眼光去觀察和抽象這個世界中的事物,這裡的事物可以是一些商業邏輯、可以是一些處理流程,然後用高層次的介面去描述這些行為和契約。當你在越抽象的層次上將這些行為和契約描述清楚後,你所設計的系統就是越符合開閉原則的。

SpringMVC框架在面向物件設計上,做出了絕佳的示範。它通過高度抽象的介面,描述出了一次請求處理的流程,從而讓整個框架從一開始就是符合開閉原則的。同時它也提供了這些介面的一系列預設實現類,讓你不需要很複雜的配置,就能很好的使用SpringMVC進行開發。抽象的確是個利器,但是框架絕不能執行在空中樓閣中,SpringMVC提供的的這一系列預設實現類必須要有容身之所。聰明的你可能早已想到:Spring IOC容器。這就引出了我要說的第二點。

2.配置元素的物件化

所有的框架,都需要有這樣一個功能,叫做:配置元素的物件化。因為幾乎所有的框架,都將配置元素集中到外部的xml配置檔案中,然後在框架的初始化流程中,對這些配置檔案進行解析,再變成java世界中的一個個物件供框架使用,這整個過程,可以被稱為配置元素的物件化。為什麼要有配置檔案呢?這個問題的回答也是很簡單,因為沒有人會想要使用一個配置散佈在框架中各個java類原始碼裡面的框架。框架也不允許使用者這樣子做,因為框架在釋出的時候,提供的是一個個jar包檔案,jar包內是已經編譯好的class檔案。配置檔案由使用者外部提供,框架對它進行解析,使用者能得到集中配置的好處,框架也樂於這樣子,可以說是合情合理。

那麼作為Spring產品族的新成員,SpringMVC在設計的時候,相信設計者們不做它想,這一個“配置元素的物件化”功能既然不可避免,那麼使用Spring IOC容器,通過bean配置檔案來配置SpringMVC,絕對是不二之選。不可能像Struts2一樣,內部再搞一個別的容器,因為Spring容器本身已經是被高度設計,而且已經在java世界獲得巨大成功。從推廣的角度上來說,如果對spring容器的所有知識,都可以完整的應用到SpringMVC,那麼對於開發者無疑是一個極大的吸引力。

剩下的問題就只有:到底該如何將Spring容器和SpringMVC的初始化過程整合起來呢?

答案就是WebApplicationContext介面,更具體點說,是XmlWebApplicationContext這個Spring上下文實現類。SpringMVC也使用了這一個為了將Spring容器和Web環境整合而特意設計的Spring上下文類。我們開啟WebApplicationContext的原始碼:

01 package org.springframework.web.context;
02
03 import javax.servlet.ServletContext;
04
05 import org.springframework.context.ApplicationContext;
06
07 public interface WebApplicationContext extends ApplicationContext {
08
09 String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
10
11 String SCOPE_REQUEST = "request";

相關推薦

SpringMVC原始碼剖析- DispatcherServlet前世今生

上一篇文章《SpringMVC原始碼剖析(一)- 從抽象和介面說起》中,我介紹了一次典型的SpringMVC請求處理過程中,相繼粉墨登場的各種核心類和介面。我刻意忽略了原始碼中的處理細節,只列出最簡單的類甚至是介面類,目的就是讓大家先從最高層次的抽象意義上來審視Spr

STL原始碼剖析空間配置器

歡迎大家來訪二笙的小房子,一同學習分享生活! 文章目錄 1. 寫在前面 2. SGI空間配置器 2.1 SGI標準空間配置器 2.2 SGI特殊的空間配置器,std::alloc 2.3 構造和析構基本工具 2.4 空間

Redis原始碼剖析--簡單動態字串

 Redis沒有使用C語言的字串結構,而是自己設計了一個簡單的動態字串結構sds。它的特點是:可動態擴充套件記憶體、二進位制安全和與傳統的C語言字串型別相容。下面就從原始碼的角度來分析一下Redis中sds的實現。   1 SDS的定義 // sds相容傳統C風格字串,所以起了

STL原始碼剖析

opp(Object-Oriented Programming)vs GP(Generic Programming) OPP:企圖將datas和methods分開來 GP:企圖將datas和methods分開來 分開的好處: (1)containers和algorith

darknet原始碼剖析

進入run_detector函式: char *prefix = find_char_arg(argc, argv, "-prefix", 0); 其中find_char_arg位於src/utils.c檔案中, char *find_char_arg(int argc

SpringMVC原始碼剖析- HandlerExceptionResolver異常解析器家族揭祕

在Spring MVC中,所有用於處理在請求處理過程中丟擲的異常,都要實現HandlerExceptionResolver介面。HandlerExceptionResolver是Spring MVC提供的非常好的通用異常處理工具,不過需要注意的是,它只能處理請求過程中丟擲的

SpringMVC原始碼分析之請求如何轉發到對應的Controller

        在前一篇對DispatcherServlet的分析中,初略的過了下請求是如何處理的,本文將重點分析,HandlerMapping與HandlerAdapter是如何工作的          在web容器啟動的過程中,會初初始化一系列SpringMVC所需

SpringMVC原始碼剖析- 從抽象和介面說起

註明:文章是本人在中國開源網上看到的經典文章,出處:http://my.oschina.net/lichhao 作者:相見歡 SpringMVC作為Struts2之後異軍突起的一個表現層框架,正越來越流行,相信javaee的開發者們就算沒使用過Sprin

spring原始碼剖析Spring預設標籤解析及註冊實現

在使用spring的時候,我也經常會使用到bean標籤,beans標籤,import標籤,aop標籤等。 下面主要為讀者介紹spring的預設的自帶標籤的解析流程。 驗證模式(DTD&XSD) dtd基本已被淘汰,現在spring的驗證模式基本都是採用xsd檔案

SpringMVC原始碼剖析SpringMVC整體架構分析和建立

先看一下Servlet的繼承結 前面的Servlet體系我都有講過HttpServlet實現了根據動作分發請求 其他結構重要的類為HttpServletBean,FrameworkServlet ,DispatcherServlet 在Spring中實現了XXXAware

SpringMVC原始碼分析-URL對映的註冊

​ 首先我們來看下AbstractHandlerMethodMapping這個類,它實現了InitializingBean介面,裡面有個afterPropertiesSet()方法。這個介面是spring-beans這個元件的內容,想一想,平時使用搭建Spr

tomcat剖析

src tomcat logs 特性 img 連接器 默認 多個 images 本節主要分析tomcat4中的默認連接器機制。默認連接器的主要特性是:(1)使用了一個對象連接池來避免多次創建對象的性能消耗(2)接收HTTP請求和處理HTTP請求采用了異步的機制,提高了吞吐量

springMVC學習總結路徑映射和請求方法限定

根路徑 後臺 mapping oca log alt public mes cti springMVC學習總結(二)路徑映射和請求方法限定 一、路徑映射 無參數的訪問路徑 對springmvc項目的訪問路徑,是由根路徑和子路徑組成;在註解式開發中,根路徑標註在類名之上,子

Java SpringMVC框架學習httpServeltRequest和Model傳值的區別

urn ont ppi mode array style att 區別 () 為什麽大多程序在controller中給jsp傳值時使用model.addAttribute()而不使用httpServeletRequest.setAttribute()? 事實上model數

SpringMVC基礎配置

ads 註意 ram 客戶 處理 ping 聯合 erp 就是 上一張:SpringMVC環境搭建(一) 今天我們來說說SpringMVC的基礎配置。目前越來越多的主流框架都支持註解,同時我們無敵的Spring也支持基於註解的"零配置"。 註解相比XML的優勢:它可以充

Flume NG原始碼分析支援執行時動態修改配置的配置模組

在上一篇中講了Flume NG配置模組基本的介面的類,PropertiesConfigurationProvider提供了基於properties配置檔案的靜態配置的能力,這篇細說一下PollingPropertiesFileConfigurationProvider提供的執行時動態修改配置並生效的

GCC原始碼分析——前端

原文連結:http://blog.csdn.net/sonicling/article/details/6706152   從這一篇開始,我們將從原始碼的角度來分析GCC如何完成對C語言原始檔的處理。GCC的內部構架在GCC Internals(搜“gccint.pdf”,或者見[

Spring原始碼解析——元件註冊2

    import com.ken.service.BookService; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.

Android Hook框架adbi原始碼淺析

二、libbase 其實上面載入完SO庫後,hook的功能我們完全可以自己在動態庫中實現。而adbi作者為了方便我們使用,編寫了一個通用的hook框架工具即libbase庫。libbase依然在解決兩個問題:1.獲取要hook的目標函式地址;2.給函式打二進位制補丁即inline hook。 關於獲取ho

Glide原始碼分析——從用法來看之load&into方法

上一篇,我們分析了with方法,文章連結: https://blog.csdn.net/qq_36391075/article/details/82833260 在with方法中,進行了Glide的初始化,建立了RequesManger,並且綁定了生命週期,最終返回了一個Reques