剖析SSH核心原理(一) .
阿新 • • 發佈:2019-01-02
在我前面的文章中,也試圖總結過SSH,見http://blog.csdn.net/shan9liang/article/details/8803989,隨著知識的積累,總感覺以前說得比較籠統,思路不夠清晰,所以打算寫幾篇文章再稍微深入地剖析一下SSH,只能說是稍微,因為這三個框架的架構設計和基本原理,並不是通過幾篇文字,就能說出所以然的,時間和精力有限,只是希望能通過這幾篇簡練的文字使大家對ssh的認識再上一個臺階。
一、框架的本質
在說Struts2,Spring和Hibernate核心原理之前,我覺得應該先搞明白以下三個問題,簡短概括如下:
1、什麼框架?
框架並不是什麼神聖的東西,它只是一組jar包而已,其本質是對jdk功能的擴充套件,包含了一系列最佳實踐,作用是解決某個領域的問題。
從廣義上說,jdk也可以看做一個複合框架,它提供的api同樣是為了解決各個領域的問題,例如java io解決檔案操作的問題,java socket解決網路通訊的問題等等。
2、框架從何而來?
從框架的本質看,框架的產生就是為了解決一個又一個在開發中所遇到的問題。不同的框架是為了解決不同領域的問題。
3、為什麼要使用框架?
框架是因解決問題而來,而且它帶來了解決某一領域問題的最佳實踐,實際是無數程式設計師在經過了無數次嘗試後,總結出來處理特定問題的特定方法,如果我們把每個程式設計師的自由發揮看做是一條通往成功的路徑,最佳實踐就是其中的最短路徑,它能夠極大地解放生產力。
二、框架的適用範圍
Web開發模式中最普遍的一種是“分層開發模式”,分層開發模式是指,在開發J2ee程式時,將整個程式根據功能職責進行縱向劃分,比較常見的劃分方法是:表示層,業務層,持久層。具體不再贅述,做java web開發,這是基本常識了。根據業務需求作用域的不同,這種分層會產生不同程度的變化,可能會細化更多層,也可能會合並,不能為了分層而分層,一切脫離業務架構的設計都是虛幻的。
我們最為熟悉得Struts,Spring,Hibernate正是為了應對各個層次的程式設計問題的最佳實踐。即Struts對應表示層,Hibernate對應持久層,而Spring比較特殊,我們暫時簡單地認為它對應業務層,後面我們再詳細討論。
三、Struts2
說了這麼多,終於進入文章的重心了。
從巨集觀看,Struts2是一個運行於Web容器的表示層框架,其核心作用是幫助我們處理http請求。
Struts2遵循Servlet標準,通過實現標準的Filter介面進行Http請求的處理,通過在web.xml指定這個實現類StrutsPrepareAndExecuteFilter,就可以將Struts2引入到應用中來。
而Filter的生命週期也成為我們對整個Struts2進行邏輯主線劃分的主要依據。
主線1:Struts2初始化-----Filter的init方法驅動執行。
主線2:Struts2處理Http請求------Filter的doFilter方法驅動
示意圖:
1、Struts2初始化
Struts2初始化只在web容器啟動時執行一次,啟動的成敗關係整個web應用的啟動成敗。初始化主線貫穿Struts2對其內建物件的建立和快取過程,將Struts2的執行環境完整地建立起來。
我們從“資料”和“行為”兩個角度來分析,構成Struts2整個初始化過程的主要元素,就可以分為“資料結構的定義”和“初始化行為的操作介面”兩部分。
(1)從資料結構定義的角度,Struts2圍繞管理Struts2內建物件的容器展開,該容器成為初始化主線中的核心構成元素。而另一類配置元素PackageConfig作為事件請求對映的配置元素也可作為構成元素。介面定義和實現類分別為:Container,ContainerImp,PackageConfig。
(2)從初始化行為的操作介面的角度,則由另外兩個元素完成,載入介面和構造器。介面為:ConfigurationProvider(使用多重繼承將Container和PackageConfig兩類配置載入介面進行統一),ContainerProvider(Container的配置載入介面,其實現類需要負責初始化容器中的所有物件),PackageProvider(PackageProvider介面,其實現類負責初始化用於處理事件請求的配置物件),ContainerBuilder(Container構造器,用於初始化時構造容器),PackageConfigBulider(PackageProvider構造器,用於初始化時構造PackageProvider)
還有兩個輔助元素承載上述介面,驅動整個初始化流程:ConfigurationManager(配置行為操作代理類,包含所有ContainerProvider和PackageProvider的實現以及配置的結構化資料Configuration),Configuration(配置資料的管理類,執行時獲取配置的基本介面,承載所有配置的結構化資料和操作方法)
初始化步驟詳細示意圖
2、Struts2處理Http請求
Struts2處理Http請求又分兩個階段:Http請求預處理階段(以後統稱階段1),XWork執行業務邏輯(以後統稱階段2)
嚴格意義上說,Struts2是由兩個不同的框架組成,一個是執行在階段1的Struts2,負責將Web容器與MVC分離,,一個是執行在階段2的XWork,真正的MVC實現。
(1)階段1的主要元素
Dispatcher,整個Struts2的核心,被稱為核心分發器,是Struts2進行http請求預處理的核心場所,更是將Http請求與web容器解耦並進行邏輯處理轉發的執行驅動中心。
PrepareOperations,HTTP預處理類,進行Http請求預處理的操作集合
ExecuteOperations,HTTP處理執行類,進行Http請求邏輯處理的操作集合
(2)階段2的主要元素
這一階段,程式控制權交給了XWork框架,涉及XWork框架的七大元素,這七大元素構成一條生產線,完成對http請求的處理。
ActionProxy,整個生產線的入口,封裝了所有執行細節。
ActionInvocation,生產線的排程者,負責排程整個生產線中各個元素的執行次序。
Interceptor,生產線上的工序,豐富生產線的功能。
Action,生產線上的核心工序,負責核心業務邏輯的呼叫或實現。
ActionContext,提供整個生產線需要的資料環境。
ValueStack,提供表示式計算的工具類,Xwork資料訪問的基礎。(後面細說)
Result,生產線末端裝置,輸出生產線的生產結果。
結合階段1的核心分發器,根據七大元素的呼叫關係,我們可以得到如下示意圖:
從圖中,我們可以看出以下幾點:
(1)Dispatcher是Xwork框架的呼叫者和驅動者
(2)XWork生產線依賴兩個資料流:ActionContext和ValueStack
ActionContext是一個獨立的資料結構,無論是請求引數,處理返回值,甚至一些遠端的Web容器物件,都被封裝在ActionContext內部,成為XWork執行所依賴的資料基礎。值得注意的是,ActionContext採用ThreadLocal保證執行緒安全。
ValueStack本身也是一個數據結構,從屬於ActionContext,主要是對OGNL計算進行擴充套件,因此,位於ActionContext之中的ValueStack則賦予了ActionContext進行資料計算的功能,從而使得ValueStack自身成為一個可以進行資料訪問的環境。
插入一點OGNL相關的東西。 如果我們要資料在View層和java世界中互相流轉,就回在“字串”和“物件樹”之間存在不匹配性,這個不匹配性源於Web是一個“弱型別”的平臺,而java卻是一個具有豐富資料型別的“強型別”的平臺。同一個物件在兩個平臺之間互動,就必須要一個“翻譯”,也就是我們說的“表示式引擎”,它充當著“翻譯橋樑”的作用,保證資料能夠順利地在MVC的各個層次進行流轉。而OGNL就是Struts2選擇的表示式引擎。
(3)XWork生產線所依賴的控制流:事件處理驅動元素-----ActionProxy,ActionInvocation,事件處理節點-----Interceptor,Action, Result 有關這五大元素的作用和關係,我們用下面這個比喻來詮釋。 四、本篇總結 至此,我們圍繞初始化和處理Http請求兩大主線說明Struts作為表示層框架的基本原理,用一張圖概括本篇脈絡 隨著知識的積累,理解自然深入,下篇,我們將繼續探究Hibernate的核心原理……
插入一點OGNL相關的東西。 如果我們要資料在View層和java世界中互相流轉,就回在“字串”和“物件樹”之間存在不匹配性,這個不匹配性源於Web是一個“弱型別”的平臺,而java卻是一個具有豐富資料型別的“強型別”的平臺。同一個物件在兩個平臺之間互動,就必須要一個“翻譯”,也就是我們說的“表示式引擎”,它充當著“翻譯橋樑”的作用,保證資料能夠順利地在MVC的各個層次進行流轉。而OGNL就是Struts2選擇的表示式引擎。
(3)XWork生產線所依賴的控制流:事件處理驅動元素-----ActionProxy,ActionInvocation,事件處理節點-----Interceptor,Action, Result 有關這五大元素的作用和關係,我們用下面這個比喻來詮釋。 四、本篇總結 至此,我們圍繞初始化和處理Http請求兩大主線說明Struts作為表示層框架的基本原理,用一張圖概括本篇脈絡 隨著知識的積累,理解自然深入,下篇,我們將繼續探究Hibernate的核心原理……