JavaEE 輕量級常用框架原理

一 Hibernate

我們從三個角度理解一下Hibernate:

1 Hibernate是對JDBC進一步封裝

   原來沒有使用Hiberante做持久層開發時,存在很多冗餘,如:各種JDBC語句,connection的管理,所以出現了Hibernate把JDBC封裝了一下,我們不用操作數據,直接操作它就行了。

2 我們再從分層的角度來看

   我們知道非常典型的三層架構:表示層,業務層,還有持久層。Hiberante也是持久層的框架,而且持久層的框架還有很多,比如:IBatis,Nhibernate,JDO,OJB,EJB等等。

3 Hibernate是開源的一個ORM(對象關係映射)框架。

  ORM,即Object-Relational Mapping,它的作用就是在關係型數據庫和對象之間做了一個映射。從對象(Object)映射到關係(Relation),再從關係映射到對象。這樣,我們在操作數據庫的時候,不需要再去和複雜SQL打交道,只要像操作對象一樣操作它就可以了(把關係數據庫的字段在內存中映射成對象的屬性)。

4 Hibernate的核心:

 從上圖中,我們可以看出Hibernate六大核心接口,兩個主要配置文件,以及他們直接的關係。Hibernate的所有內容都在這了。那我們從上到下簡單的認識一下,每個接口進行一句話總結。
  • 1、Configuration接口:負責配置並啓動Hibernate

  • 2、SessionFactory接口:負責初始化Hibernate

  • 3、Session接口:負責持久化對象的CRUD操作

  • 4、Transaction接口:負責事務

  • 5、Query接口和Criteria接口:負責執行各種數據庫查詢

    注意:Configuration實例是一個啓動期間的對象,一旦SessionFactory創建完成它就被丟棄了。
    

5 Hibernate的優/缺點:

優點:

  • 1)更加對象化

    以對象化的思維操作數據庫,我們只需要操作對象就可以了,開發更加對象化。

  • 2)移植性

    因爲Hibernate做了持久層的封裝,你就不知道數據庫,你寫的所有的代碼都具有可複用性。

  • 3)Hibernate是一個沒有侵入性的框架,沒有侵入性的框架我們稱爲輕量級框架。

    對比Struts的Action和ActionForm,都需要繼承,離不開Struts。Hibernate不需要繼承任何類,不需要實現任何接口。這樣的對象叫POJO對象。

  • 4)Hibernate代碼測試方便。

  • 5)提高效率,提高生產力。

缺點:

  • 1)使用數據庫特性的語句,將很難調優

  • 2)對大批量數據更新存在問題

  • 3)系統中存在大量的攻擊查詢功能

二 Struts2

1 源碼

https://github.com/apache/struts

2 詳細步驟

  • 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來創建的。

3 簡述:

一個請求經過層層過濾器以及核心控制器到達Action映射,Action映射進行路徑檢查後(讀取web.xml文件看是否要被核心控制器處理)將請求轉發給核心控制器,核心控制器再將請求轉發給Action代理,它通過一個組件ConfigurationManager讀取struts.xml中的配置信息,找到對應的Action,存放到ActionInvocation.請求繼續經過一系列攔截器到達Action.Action返回邏輯視圖名,指向一個View視圖,解析視圖,如果有標籤還會加載標籤,最後反向經過層層攔截器做出相應,瀏覽器渲染視圖。

三 SpringMVC

1 SpringMVC框架介紹

  Spring MVC屬於SpringFrameWork的後續產品,已經融合在Spring Web Flow裏面。spring 框架提供了構建 Web 應用程序的全功能 MVC 模塊。使用 Spring 可插入的 MVC 架構,可以選擇是使用內置的 Spring Web 框架還是 Struts 這樣的 Web 框架。通過策略接口,Spring 框架是高度可配置的,而且包含多種視圖技術,例如 JavaServer Pages(JSP)技術、Velocity、Tiles、iText 和 POI。Spring MVC 框架並不知道使用的視圖,所以不會強迫您只使用 JSP 技術。
  Spring MVC 分離了控制器、模型對象、分派器以及處理程序對象的角色,這種分離讓它們更容易進行定製。Spring的MVC框架主要由DispatcherServlet、處理器映射、處理器(控制器)、視圖解析器、視圖組成。

2 SpringMVC原理圖

3. SpringMVC接口解釋

  • DispatcherServlet接口:

     Spring提供的前端控制器,所有的請求都有經過它來統一分發。在DispatcherServlet將請求分發給Spring Controller之前,需要藉助於Spring提供的HandlerMapping定位到具體的Controller。
    
  • HandlerMapping接口:

     能夠完成客戶請求到Controller映射。
    
  • Controller接口:

        需要爲併發用戶處理上述請求,因此實現Controller接口時,必須保證線程安全並且可重用。
    
        Controller將處理用戶請求,這和Struts Action扮演的角色是一致的。一旦Controller處理完用戶請求,則返回ModelAndView對象給DispatcherServlet前端控制器,ModelAndView中包含了模型(Model)和視圖(View)。
    
        從宏觀角度考慮,DispatcherServlet是整個Web應用的控制器;從微觀考慮,Controller是單個Http請求處理過程中的控制器,而ModelAndView是Http請求過程中返回的模型(Model)和視圖(View)。
    
  • ViewResolver接口:

         Spring提供的視圖解析器(ViewResolver)在Web應用中查找View對象,從而將相應結果渲染給客戶。
    

4 SpringMVC運行原理

  • 1.客戶端請求提交到DispatcherServlet
  • 2.由DispatcherServlet控制器查詢一個或多個HandlerMapping,找到處理請求的Controller
  • 3.DispatcherServlet將請求提交到Controller
  • 4.Controller調用業務邏輯處理後,返回ModelAndView
  • 5.DispatcherServlet查詢一個或多個ViewResoler視圖解析器,找到ModelAndView指定的視圖
  • 6.視圖負責將結果顯示到客戶端

5 DispatcherServlet

DispatcherServlet是整個Spring MVC的核心,它負責接收HTTP請求組織協調Spring MVC的各個組成部分。其主要工作有以下三項:
  • 1.截獲符合特定格式的URL請求。
  • 2.初始化DispatcherServlet上下文對應的WebApplicationContext,並將其與業務層、持久化層的WebApplicationContext建立關聯。
  • 3.初始化Spring MVC的各個組成組件,並裝配到DispatcherServlet中。

四 hibernate VS mybatis

1. hibernate是全自動,而mybatis是半自動。

hibernate完全可以通過對象關係模型實現對數據庫的操作,擁有完整的JavaBean對象與數據庫的映射結構來自動生成sql。而mybatis僅有基本的字段映射,對象數據以及對象實際關係仍然需要通過手寫sql來實現和管理。

2. hibernate數據庫移植性遠大於mybatis。

hibernate通過它強大的映射結構和hql語言,大大降低了對象與數據庫(oracle、mysql等)的耦合性,而mybatis由於需要手寫sql,因此與數據庫的耦合性直接取決於程序員寫sql的方法,如果sql不具通用性而用了很多某數據庫特性的sql語句的話,移植性也會隨之降低很多,成本很高。

3. hibernate擁有完整的日誌系統,mybatis則欠缺一些。

hibernate日誌系統非常健全,涉及廣泛,包括:sql記錄、關係異常、優化警告、緩存提示、髒數據警告等;
而mybatis則除了基本記錄功能外,功能薄弱很多。

4. mybatis相比hibernate需要關心很多細節

hibernate配置要比mybatis複雜的多,學習成本也比mybatis高。但也正因爲mybatis使用簡單,才導致它要比hibernate關心很多技術細節。

mybatis由於不用考慮很多細節,開發模式上與傳統jdbc區別很小,因此很容易上手並開發項目,但忽略細節會導致項目前期bug較多,因而開發出相對穩定的軟件很慢,而開發出軟件卻很快。hibernate則正好與之相反。但是如果使用hibernate很熟練的話,實際上開發效率絲毫不差於甚至超越mybatis。

5. sql直接優化上,mybatis要比hibernate方便很多

由於mybatis的sql都是寫在xml裏,因此優化sql比hibernate方便很多。而hibernate的sql很多都是自動生成的,無法直接維護sql;

雖有hql,但功能還是不及sql強大,見到報表等變態需求時,hql也歇菜,也就是說hql是有侷限的;
hibernate雖然也支持原生sql,但開發模式上卻與orm不同,需要轉換思維,因此使用上不是非常方便。
總之寫sql的靈活度上hibernate不及mybatis。

總結:
mybatis:小巧、方便、高效、簡單、直接、半自動
hibernate:強大、方便、高效、複雜、繞彎子、全自動

五 Struts2 VS SpringMVC

1 核心機制

    spring mvc的入口是servlet,而struts2是filter,這樣就導致了二者的機制不同。

2 攔截機制

    Struts2是類級別的攔截, 一個類(Action)對應一個request上下文,SpringMVC是方法級別的攔截,一個方法對應一個request上下文;而方法同時又跟一個url對應,所以說從架構本身上SpringMVC就容易實現restful url;而struts2的架構實現起來要費勁;因爲Struts2中Action的一個方法可以對應一個url,而其類屬性卻被所有方法共享,這也就無法用註解或其他方式標識其所屬方法了。

3 獲取請求的數據

SpringMVC的方法之間基本上獨立的,獨享request response數據,請求數據通過參數獲取,處理結果通過ModelMap交回給框架,方法之間不共享變量;Struts2雖然方法之間也是獨立的,但其所有Action變量是共享的

4 返回響應的數據

Struts採用值棧存儲請求和響應的數據,通過OGNL存取數據, springmvc通過參數解析器是將request請求內容解析,並給方法形參賦值,將數據和視圖封裝成ModelAndView對象,最後又將ModelAndView中的模型數據通過reques域傳輸到頁面。Jsp視圖解析器默認使用jstl。

5 開發效率和使用性能

spring會稍微比struts快。spring mvc是基於方法的設計,而sturts是基於類,每次發一次請求都會實例一個action,每個action都會被注入屬性,而spring基於方法,粒度更細,但要小心把握像在servlet控制數據一樣。spring mvc使用更加簡潔,開發效率Spring MVC確實比struts2高。   

6 ajax集成

SpringMVC集成了Ajax,使用非常方便,只需一個註解@ResponseBody就可以實現,然後直接返回響應文本即可,而Struts2攔截器集成了Ajax,在Action中處理時一般必須安裝插件或者自己寫代碼集成進去,使用起來也相對不方便。

7 驗證支持

SpringMVC驗證支持JSR303(*JSR 303 – Bean Validation 是一個數據驗證的規範,將驗證邏輯與相應的域模型進行綁定。在應用程序中,通過使用 Bean Validation 或是你自己定義的 constraint,例如 @NotNull, @Max, @ZipCode, 就可以確保數據模型(JavaBean)的正確性。constraint 可以附加到字段,getter 方法,類或者接口上面。對於一些特定的需求,用戶可以很容易的開發定製化的 constraint。Bean Validation 是一個運行時的數據驗證框架,在驗證之後驗證的錯誤信息會被馬上返回。Hibernate Validator 是 Bean Validation 的參考實現 . Hibernate Validator 提供了 JSR 303 規範中所有內置 constraint 的實現,除此之外還有一些附加的 constraint*),處理起來相對更加靈活方便,而Struts2驗證比較繁瑣。

8 設計思想(OOP)

Struts2更加符合OOP的編程思想, SpringMVC就比較謹慎,在servlet上擴展。

9 架構設計

9.1 設計實現

    從設計實現角度來說,我覺得SpringMVC更加清晰。即使我們去對比Struts2的原理圖和SpringMVC的類圖,它依然很讓人困惑,遠沒有SpringMVC更加直觀。
SpringMVC設計思路:將整個處理流程規範化,並把每一個處理步驟分派到不同的組件中進行處理。 這個方案實際上涉及到兩個方面: 
  • 處理流程規範化 —— 將處理流程劃分爲若干個步驟(任務),並使用一條明確的邏輯主線將所有的步驟串聯起來

  • 處理流程組件化 —— 將處理流程中的每一個步驟(任務)都定義爲接口,併爲每個接口賦予不同的實現模式

    處理流程規範化是目的,對於處理過程的步驟劃分和流程定義則是手段。因而處理流程規範化的首要內容就是考慮一個通用的Servlet響應程序大致應該包含的邏輯步驟:

  • 步驟1:對Http請求進行初步處理,查找與之對應的Controller處理類(方法) ——HandlerMapping

  • 步驟2:調用相應的Controller處理類(方法)完成業務邏輯 ——HandlerAdapter

  • 步驟3:對Controller處理類(方法)調用時可能發生的異常進行處理 ——HandlerExceptionResolver

  • 步驟4:根據Controller處理類(方法)的調用結果,進行Http響應處理 ——ViewResolver

    正是這基於組件、接口的設計,支持了SpringMVC的另一個特性:行爲的可擴展性。

9.2 設計原則更加明朗。

【Open for extension /closed for modification】 

這條重要的設計原則被寫在了spring官方的reference中SpringMVC章節的起始段: 

A key design principle in SpringWeb MVC and in Spring in general is the “Open for extension, closed for modification” principle.
並且重點很好地體現在SpringMVC的實現當中,可以擴展,但卻不能改變。我曾經擴展過Spring的IOC、AOP功能,這一點SpringMVC應該和Spring一脈相承。

9.3 組件化的設計方案和特定的設計原則讓SpringMVC形散神聚。

  • 神 —— SpringMVC總是沿着一條固定的邏輯主線運行
  • 形 —— SpringMVC卻擁有多種不同的行爲模式

    SpringMVC是一個基於組件的開發框架,組件的不同實現體系構成了“形”;組件的邏輯串聯構成了“神”。因此,“形散神不散”: SpringMVC的邏輯主線始終不變,而行爲模式卻可以多種多樣。

10 和Spring集成

spring MVC和Spring是無縫的。從這個項目的管理和安全上也比Struts2高(當然Struts2也可以通過不同的目錄結構和相關配置做到SpringMVC一樣的效果,但是需要xml配置的地方不少)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章