對比Struts和SpringMVC

   我們之前學習了Struts1、Struts2、SpringMVC,他們都屬於前端框架,都是對MVC模式的實現,下面對比學習一下這三個框架。

   現在用的比較多的是Struts2、SpringMVC, Struts1官方已經停止更新,現在用的也比較少,Struts2其實並不是Struts1的升級,而是繼承了WebWork的血統,集成了二者的優點,是在 struts 1和WebWork的技術基礎上進行了合併的全新框架,Struts1和Struts2在體系結構上有着較大的差別。Struts 2以WebWork爲核心,採用攔截器的機制來處理用戶的請求,這樣的設計也使得業務邏輯控制器能夠與ServletAPI完全脫離開,所以Struts 2可以理解爲WebWork的更新產品。雖然從Struts 1到Struts 2有着太大的變化,但是相對於WebWork,Struts 2的變化很小。

   之前看過一些文章,分別對三種框架進行了較詳細的剖析,基於此分別介紹比較一下這三種框架。

   一、Struts1

   Struts1框架是apache公司的開源子項目,是基於mvc邏輯分層的web層框架實現。是出現最早的web層框架,應用最廣發。Struts1框架重點關注的是控制層,對於視圖層只是提供了大量的標籤,對於model層的影響微乎其微,現在用的也越來越少了。

      

   工作原理:

   1、服務器啓動,Web應用啓動時就會加載web.xml初始化actionServlet和記載struts配置文件(struts-config.xml),讀配置信息到內存中,供以後action調用。

   2、用戶通過客戶端向服務器發出一個請求,http://localhost:8080/struts_login/login.do 

   3、tomcat會創建出HttpRequest和HttpResponse實例,並根據用戶的Method請求方式,調用中央控制器的doGet或者doPost方法。我們已經在web.xml配置了所有符合某特定格式的請求都將由struts指定的Servlet來處理。比如:只要是以.do結尾的請求(*.do)都由 org.apache.struts.action.ActionServlet來對其進行處理.ActionServlet會拿到用戶的請求,並且去分析這個URL,ActionServlet中央控制器會截下 /login. 截下來之後,它是爲了去struts-config.xml這個配置文件裏面找<action>標籤path屬性的值等於所截部分的那個 Action,將Action標籤裏面的信息放在ActionMapping裏面。

   4、根據ActionMapping中的name名稱查找ActionForm,如果配置了ActionForm,那麼就到request或session中查找,如果在request或session中存在已經創建的ActionForm,那麼將返回;如果不存在,那麼會根據ActionForm的完成路徑採用反射進行創建,再將創建好的ActionForm放到reqeust或session中。

   5、首先執行ActionForm中的reset方法進行重置,然後得到表單中所有輸入域的name名稱,再調用request.getParameterValues(),根據name名稱得到相應的值,最後將表單中的數據全部放到一個map中,map中的key爲表單輸入域的名稱,map的value位表單輸入域的值(字符串數組),接下來調用一個第三方組件BeanUtils,將Map中的值,根據ActionForm中的setter方法設置到ActionForm上。

   6、根據Action的完成類名稱到Map中查找,如果存在就在返回Action對象,否則根據Action類的完整名稱採用反射去創建,再將創建好的Action放到Map中。所以struts1的Action是單實例的,存在線程安全問題。找到對應的action之後,ActionServlet會把表單提交的數據給存放(生成對應調用 set/get方法)到struts-config中相應的action標籤的name屬性值指定的actionform類中(若有, [actionform的子類,並且在form-bean標籤中配置了,若要進行數據驗證可以在actionform中覆蓋validate方法,推薦使用js,減輕服務器負擔]),同時把actionform和當前HttpServletrequest 對象注入到代調用的action方法中。

   7、執行用戶自定義的Action中的Execute方法,將ActionMapping,ActionForm,request,response傳遞過去,將ActionForward返回給ActionServlet。

   8、根據返回的ActionForward完成轉向,ActionForward對象根據此action配置的<forward>匹配name進而調轉到對應path的jsp頁面上,返回結果給客戶端。

   二、Struts2

   Struts2其實並不是Struts1的升級,而是繼承了WebWork的血統,集成了二者的優點,是在 struts 1和WebWork的技術基礎上進行了合併的全新框架,是基於Filter攔截實現的。


   工作原理:

   1、Tomcat服務器啓動,Web應用啓動時,首先會加載web.xml文件,然後初始化Filter過濾器,初始化org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter監聽程序。這時,會把Struts2的配置文件讀到內存裏面(如果是Struts2與Spring集成,會是Listner先啓動,Spring完成Struts2的Action的創建,不耽誤Struts2文件的初始化)供以後Action調用。

   2、用戶訪問瀏覽器,發送請求,指向Servlet容器。

   3、容器tomcat會創建出HttpRequest和HttpResponse實例;並通過web.xml文件映射請求,截取並獲取控制器的名稱。

   4、然後容器調用StrutsPrePareAndExecutionFilter,StrutsPrepareAndExecuteFilter通過ActionMapper來決定獲取Action的信息。

   5、如果ActionMapper決定需要調用某個Action,StrutsPrepareAndExecuteFilter把請求的處理交給Action的代理ActionProxy;

   6、控制器調用ActionProxy

   7、ActionProxy通過ConfigurationManager讀取strut.xml配置文件來獲取action和interceptor的信息,找到需要調用的Action類。

   8、ActionProxy把request請求傳遞給ActionInvocation對象。

   9、ActionInvocation實例使用命令模式來調用,依次調用action和interceptor。

   10、根據action的配置信息,產生result,result信息返回給actionInvocation。

   11、返回結果給客戶端。

   特點:

   1、線程模式,每一次請求都會產生一個新的實例處理請求,多線程環境下沒有數據同步問題。

   2、引入數據的依賴注入【頁面表單數據注入到Action的注入、實例對象的注入,通過set方法注入】

   3、基於AOP的攔截器,可以在每次請求前後靈活控制。

   4、配置文件支持表單式,基於約定大於配置,簡化配置。

   5、內置以插件形式支持ajax如dojo,支持多種末班展示jsp、freemarker,veiocity等。

   三、SpringMVC

   SpringMVC是基於Servlet攔截實現的,主要由前端控制器(DispatcherServlet)、映射處理器(HandlerMapping)、適配器(HandlerAdapter)、攔截器(HandlerInterceptor)、控制器(Controller)、視圖解析器(ViewResolver)、視圖(View)這幾部分構成。

      

   工作原理:

   1、客戶端發出一個http請求給web服務器,web服務器對http請求進行解析,如果匹配DispatcherServlet的請求映射路徑(在web.xml中指定),web容器將請求轉交給DispatcherServlet。

   2、DipatcherServlet接收到這個請求之後將根據請求的信息(包括URL、Http方法、請求報文頭和請求參數Cookie等)以及HandlerMapping的配置找到處理請求的處理器(Handler)。

   3-4、DispatcherServlet根據HandlerMapping找到對應的Handler,將處理權交給Handler(Handler將具體的處理進行封裝),再由具體的HandlerAdapter對Handler進行具體的調用。

   5、Handler對數據處理完成以後將返回一個ModelAndView()對象給DispatcherServlet。

   6、Handler返回的ModelAndView()只是一個邏輯視圖並不是一個正式的視圖,DispatcherSevlet通過ViewResolver將邏輯視圖轉化爲真正的視圖View。

   7、Dispatcher通過model解析出ModelAndView()中的參數進行解析最終展現出完整的view並返回給客戶端。

   特點:

   1、線程模式:單例模式,效率好。

   2、基於方法級別的攔截,而不是基於類。更細粒度的靈活控制。

   3、通過註解簡化了多配置,但同時在代碼中增加了很多和業務不相干的代碼。

   四、比較

   這三個框架中,Struts1的效率三者當中最高。但是Struts1內部是面向抽象類編程,而不是面向接口編程的。Struts2提供了一個名爲ActionSupport的基類,雖然不是必須的,但是要想使用Struts2的功能,基本上都會繼承它。SpringMVC是面向接口編程,需要實現一個接口(配置文件時)。

   1、Struts1的入口點是Servlet,Struts2的入口點是Filter,SpringMVC入口點是Servlet。

   2、Struts2是類級別的攔截,每個請求創建一個action,然後通過調用setter方法把Request中的數據注入;SpringMVC是基於方法的攔截,一個方法對應一個Request上下文,而方法同時又跟一個URL對應。

   3、Struts2的類屬性被所有方法共享,這就無法用註解標識其所屬方法了,方法之間獨立,但是所有Action變量是共享的。SpringMVC的方法之間基本獨立,共享Request數據,請求數據通過參數獲取,處理結果通過ModelMap交回給框架,方法之間不共享變量。

   4、interceptor實現機制:struts2有自己的攔截器機制,SpringMVC用的是獨立的AOP方式。雖然struts的配置能繼承,但是struts的配置文件量還是比spring mvc大,從使用上來說spring mvc使用更加簡潔,開發效率Spring MVC確實比struts2高。

   5、SpringMVC的配置是基於IOC容器的,一方面方便SpringMVC進行擴展和增強,另一方面有利於與Spring整合;而Struts2與Spring的整合,需要Spring提供了第三方包。

   6、Struts2裏面可以沒有HttpServletRequest和HttpServletResponse,只有getter、setter或ActionContext裏的數據,這樣就會使Action比較獨立。整個web與Action無關,這個action可以在任何環境下獨立運行,也就是說,它可以最大限度的被重用。而SpringMVC不像Struts2那樣隱藏了HttpServletRequest和HttpServletResponse,而是將它們做爲了形參傳入控制器的方法中。

   7、Struts1的Action與SpringMVC的Controller一樣,都是單例的,不是線程安全的。這就意味着,每個Request請求,系統都會用原有的instance去處理。這雖然減少了對象的創建和垃圾收集的時間,但是處理多線程調用時,Controller不是線程安全的,而Struts2是線程安全的。

   小結

    感覺SpringMVC實現起來更加的清晰一些,而且緊跟時代潮流。Struts2使整個Controller徹底與Web容器解耦,可以方便地進行單元測試。而擺脫了Servlet束縛的Controller,也爲整個編程模型賦予了全新的定義。這樣的改造不僅使得表達式引擎能夠得到最大限度的發揮,同時使得整個Controller看起來更像是一個POJO,從面向對象的角度來看,POJO模式無疑也是所有程序員所追求的一個目標。三個框架雖然都是對MVC模式的實現,有各自的實現思路工作流程,各有各的優點,但也要順應時代潮流才行。


發佈了140 篇原創文章 · 獲贊 117 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章