前言
Java一度被稱為是應用最廣泛的編程語言。尤其在Java web方面,Java作為后台服務器開發語言,尤其是它跨平台一次編譯隨處運行的特性,更是受到不少企業和工程師們的愛戴。作為應用開發的主要語言,Java也需要借助其他很多優秀的框架,來實現系統或程序的完整性。針對不同的業務場景,選擇合適的框架,是每一個架構師和工程師在開發一項軟件之前,必須首先要考慮的事情。隨着時代的進步和科技的發展,Java技術框架也在日新月異的進化。
一、Struts1.0
Struts1.0是早期的應用很廣泛的web框架了,很多企業的管理系統和網站都是基於這個技術架構做的。Struts的第一個版本是在2001年5月份發布的。它的最初設想是:通過結合JSP和Servlet,使Web應用的視圖和業務/應用邏輯得以清晰地分離開來。在Struts之前,最常見的做法是在JSP中加入業務和應用邏輯,或者在Servlet中通過println()來生成視圖。
整體框架結構
基本流程是:
- 客戶端發送請求(Http Request),被struts1的核心控件器ActionServlet接收。
- ActionServlet根據struts-config.xml里的映射關系找到對就的Action,若找不到就返回500錯誤到JSP頁面。若有就在Action里的 excute()方法里執行相應的邏輯操作,比如調用Model層的方法,然后通過ActionForward,跳轉到對應的JSP頁面。
具體圖示如下:

詳細的工作原理流程如下:

二、Struts2.0
自從第一版發布以來,Struts實際上已成為業界公認的Web應用標准。Struts2.0是對1.0的改進。更完美的提現了MVC的強大之處。它是在Struts1.0的成功經驗基礎上繼續堅持對 前端控制器(Front Controller) 和 MVC(model-view-controller)模式 進行改進。
先來看看Struts官方站點,對於Struts2.0的架構介紹:

一個請求在Struts2框架中的處理大概分為以下幾個步驟(可查看源碼:apache/struts):
1 客戶端初始化一個指向Servlet容器(例如Tomcat)的請求
2 這個請求經過一系列的過濾器(Filter)(這些過濾器中有一個叫做ActionContextCleanUp的可選過濾器,這個過濾器對於Struts2和其他框架的集成很有幫助,例如:SiteMesh Plugin)
3 接着FilterDispatcher(現已過時)被調用,FilterDispatcher詢問ActionMapper來決定這個請是否需要調用某個Action
4 如果ActionMapper決定需要調用某個Action,FilterDispatcher把請求的處理交給ActionProxy
5 ActionProxy通過Configuration Manager詢問框架的配置文件,找到需要調用的Action類
6 ActionProxy創建一個ActionInvocation的實例。
7 ActionInvocation實例使用命名模式來調用,在調用Action的過程前后,涉及到相關攔截器(Intercepter)的調用。
8 一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果。返回結果通常是(但不總是,也可 能是另外的一個Action鏈)一個需要被表示的JSP或者FreeMarker的模版。在表示的過程中可以使用Struts2 框架中繼承的標簽。在這個過程中需要涉及到ActionMapper
在上述過程中所有的對象(Action,Results,Interceptors,等)都是通過ObjectFactory來創建的。
三、SSH框架
前幾年,只要大家一說起Java,尤其是Java web編程,大家最先想到的技術便是SSH三大框架了。對於一些初級學者來說,只知其一不知其二,沒有對SSH三大框架有更深入的研究和學習。
官方的說法:SSH是 struts+spring+hibernate的一個集成框架,是目前較流行的一種web應用程序開源框架。SSH不是一個框架,而是把多個框架(Struts、Spring以及Hibernate)緊密的結合在一起,用於構建靈活、易於擴展的多層Web應用程序。
Java EE架構大致分為以下幾個層次:
- 實體層(POJO層)
- 數據訪問層(DAO層)
- 業務邏輯層(Service層)
- 控制器層(Controller層)
- 表現層(View層)
其中SSH框架的系統從職能上分大致可以分為四層:表示層、業務邏輯層、數據持久層和域模塊層(實體層)。

由SSH構建系統的基本業務流程是:
1、在表示層中,首先通過JSP頁面實現交互界面,負責傳送請求(Request)和接收響應(Response),然后Struts根據配置文件(struts-config.xml)將ActionServlet接收到的Request委派給相應的Action處理。
2、在業務層中,管理服務組件的Spring IoC容器負責向Action提供業務模型(Model)組件和該組件的協作對象數據處理(DAO)組件完成業務邏輯,並提供事務處理、緩沖池等容器組件以提升系統性能和保證數據的完整性。
3、在持久層中,則依賴於Hibernate的對象化映射和數據庫交互,處理DAO組件請求的數據,並返回處理結果。
采用上述開發模型,不僅實現了視圖、控制器與模型的徹底分離,而且還實現了業務邏輯層與持久層的分離。這樣無論前端如何變化,模型層只需很少的改動,並且數據庫的變化也不會對前端有所影響,大大提高了系統的可復用性。而且由於不同層之間耦合度小,有利於團隊成員並行工作,大大提高了開發效率。
四、Spring MVC
Spring MVC屬於SpringFrameWork的后續產品,已經融合在Spring Web Flow里面。Spring 框架提供了構建 Web 應用程序的全功能 MVC 模塊。SpringMVC是一種web層的mvc框架,用於替代servlet(處理響應請求,獲取表單參數,表單驗證等)
1. 整體流程

具體步驟:
- 首先用戶發送請求到前端控制器,前端控制器根據請求信息(如 URL)來決定選擇哪一個頁面控制器進行處理並把請求委托給它,即以前的控制器的控制邏輯部分;圖中的 1、2 步驟;
- 頁面控制器接收到請求后,進行功能處理,首先需要收集和綁定請求參數到一個對象,這個對象在 Spring Web MVC 中叫命令對象,並進行驗證,然后將命令對象委托給業務對象進行處理;處理完畢后返回一個 ModelAndView(模型數據和邏輯視圖名);圖中的 3、4、5 步驟;
- 前端控制器收回控制權,然后根據返回的邏輯視圖名,選擇相應的視圖進行渲染,並把模型數據傳入以便視圖渲染;圖中的步驟 6、7;
- 前端控制器再次收回控制權,將響應返回給用戶,圖中的步驟 8;至此整個結束。
2. 核心流程

具體步驟:
- 第一步:發起請求到前端控制器(DispatcherServlet)
- 第二步:前端控制器請求HandlerMapping查找 Handler (可以根據xml配置、注解進行查找)
- 第三步:處理器映射器HandlerMapping向前端控制器返回Handler,HandlerMapping會把請求映射為HandlerExecutionChain對象(包含一個Handler處理器(頁面控制器)對象,多個HandlerInterceptor攔截器對象),通過這種策略模式,很容易添加新的映射策略
- 第四步:前端控制器調用處理器適配器去執行Handler
- 第五步:處理器適配器HandlerAdapter將會根據適配的結果去執行Handler
- 第六步:Handler執行完成給適配器返回ModelAndView
- 第七步:處理器適配器向前端控制器返回ModelAndView (ModelAndView是springmvc框架的一個底層對象,包括 Model和view)
- 第八步:前端控制器請求視圖解析器去進行視圖解析 (根據邏輯視圖名解析成真正的視圖(jsp)),通過這種策略很容易更換其他視圖技術,只需要更改視圖解析器即可
- 第九步:視圖解析器向前端控制器返回View
- 第十步:前端控制器進行視圖渲染 (視圖渲染將模型數據(在ModelAndView對象中)填充到request域)
- 第十一步:前端控制器向用戶響應結果
五、分布式
到了最近幾年,分布式框架中RPC和SOA等微服務架構中,主流的Java開發框架以SpringBoot/Cloud、Dubbo等分布式微服務尤為熱門。
1.RPC
RPC(Remote Process Call),即遠程服務調用,被廣泛地應用在很多企業應用中,是早期主要的服務治理方案,其流程較為簡單,客戶端consumer攜帶參數發送RPC請求到服務提供方provider,provider根據參數路由到具體函數,方法,並將執行獲得的結果返回,至此一次RPC調用完成。

2.SOA
由於簡單的RPC調用已經不能隨着時代發展滿足需求,因此復雜的業務邏輯對於分布式應用架構體系的需求愈發強烈,業務希望自己的服務是分布式部署的,請求是分流的,對數據的操作是能讀寫分離的,同時能屏蔽許多復雜需要自己編寫的底層服務,借助已有的公共服務,去快速的構建自己的應用,降低人力開發維護的成本和提高應用交付的效率,基因此,基於分布式服務思想的SOA(Service-Oriented Architecture)成了新的受追捧的架構。常見的SOA服務調用流程圖如下:

五、業界服務治理方案
業界的互聯網巨頭公司,都有屬於自己的分布式服務框架,如阿里巴巴的Dubbo,HSF,騰訊的Tars,京東的JSF,新浪的Motan,都已經是業界非常成熟的解決方案,其中開源的Dubbo和Motan受到了廣大開發者的研究對象。
縱觀這些服務框架,設計的基本思路都如上圖,無非涉及provider發布注冊,consumer訂閱,調用發起,負載均衡,服務分流和監控等模塊,並在此基礎上增加了很多玩法,形成了各具特色的分布式服務框架設計,下面就Dubbo,JSF,Motan的設計做下簡單的介紹。
(1)Dubbo:下圖是Dubbo在服務治理方面的架構設計
初始化階段:部署在Container的Provider啟動后向服務中心Registry發布並注冊自己的服務,客戶端Consumer初始化時即向Registry訂閱自己想要的服務,同時Registry對Consumer保持着一個長連接,當訂閱的服務新增或減少節點時,會及時通知到客戶端更新(此過程是異步進行的,不會影響Consumer的主流程),如此一來,客戶端Consumer便有了Provider的所有實時信息,便可以發起服務調用了。
invoke階段:客戶端Consumer從獲得的所有Provider列表中通過負載均衡等策略選出最適合調用的服務提供者Provider並發起同步調用。
Monitor階段:Consumer和Provider通過異步的方式向監控中心上報自己的需要被監控的數據。

(2)JSF:下圖是JSF在服務治理方面的架構設計
- 初始化階段:Provider啟動后向服務注冊中心發布注冊自己的服務
- invoke階段:與Dubbo不同的是,JSF的注冊中心不向Consumer推送Provider實時數據,而是在發起調用時Consumer向注冊中心詢問並獲得對應的Provider,然后組織匹配JSF協議的報文發起調用。
- Monitor階段:Provider定期向監控中心發送性能統計數據,同時Provider還會上報事件給事件中心。

(3)Motan:Motan是有名的輕量級服務框架,代碼質量很高,下圖是Motan在服務治理方面的架構設計
Motan的服務治理設計與Dubbo十分的相似,都是Provider發布注冊,Consumer訂閱與接受推送,之后發起調用。

六、分布式服務框架主要模塊名詞釋義
無論是那種SOA的架構設計,都離不開幾個模塊的功能,即Provider,Consumer,Registry,Gateway,負載均衡,服務分流,監控等,通過上述所講,應該對這些功能模塊有了初步的認識,下面就這些名詞再作下介紹
(1)Provider:服務提供者,無論是業務服務,還是一個系統中公用的SAAS,都屬於Provider
(2)Consumer:即發起調用的客戶端
(3)Registry:服務注冊中心,是分布式服務系統中的一個重要組成模塊,管理Provider的Manager,在實際的運行環境中,服務注冊中心Registry被動通知或Consumer主動詢問,在Provider有節點宕機或新增節點時,客戶端也可實時感知到,從而避免了某個Provider被無限調用或是無限閑置
(4)Gateway:網關也是分布式服務框架中不可或缺的部分,每種系統與框架都有自己的一套協議,當異構系統互相調用時,網關的作用即顯現出來,Gateway接受各種外部HTTP請求,完成相應的權限校驗,報文適配,路由轉發到對應的Provider,再將Provider返回的結果傳遞給異構系統的Consumer,完成異構系統的互相調用
(5)負載均衡,服務分流:Consumer從Registry獲得具體的Provider列表后,如何選取合適的Provider,取決與一定的負載均衡算法,常見的算法有輪詢法,隨機法,源地址哈希,加權輪詢,加權隨機等
(6)監控:接收來自Consumer和Provider異步上報的性能監控數據,對有風險的節點發出告警。