Spring MVC??
目前業(yè)內(nèi)使用得比較廣泛的 MVC 框架,就是 Spring MVC 框架。
Spring MVC 基礎(chǔ)知識(shí)
Spring MVC 是一款基于 MVC 架構(gòu)模式的輕量級(jí) Web 框架,其目的是將 Web 開發(fā)模塊化,對(duì)整體架構(gòu)進(jìn)行解耦,簡化 Web開發(fā)流程。
Spring 體系結(jié)構(gòu)
模塊
Spring4.x 框架由大約20個(gè)模塊組成。這些模塊分為核心容器(Core Container),數(shù)據(jù)訪問/集成(Data Access/Integration),Web,切面編程(AOP),Instrumentation和Test,如下圖所示。

顯然,這幅圖劃分為以下五個(gè)部分:
Core Container
Core Container包含四個(gè)模塊:Core,Beans,Context 和 表達(dá)式語言模塊。
- Core 和 Beans 模塊提供了框架的基本部分,包括控制反轉(zhuǎn) (IoC) 和依賴注入(Dependency Injection)功能。BeanFactory 是工廠模式的復(fù)雜實(shí)現(xiàn)。它消除了對(duì)程序化單例的需求,并允許將實(shí)際程序邏輯中的依賴關(guān)系的配置和規(guī)范分離。
- Context模塊建立在由Core和Beans模塊提供的堅(jiān)實(shí)基礎(chǔ)上:它訪問對(duì)象的方式類似于JNDI注冊(cè)表。Context模塊從Beans模塊中繼承它的特性,并增加對(duì)國際化的支持,例如使用資源包(resource bundles),事件傳播,資源加載,以及進(jìn)行上下文的透明創(chuàng)建,例如一個(gè) servlet 容器。Context 模塊還支持 Java EE 功能,例如 EJB,JMX,以及基本的遠(yuǎn)程處理。ApplicationContext接口是 Contex 模塊的核心內(nèi)容。
- 表達(dá)式語言模塊在運(yùn)行時(shí)為查詢和操作對(duì)象圖提供了強(qiáng)大的表達(dá)式語言。它是JSP 2.1規(guī)范中指定的統(tǒng)一表達(dá)式語言(unifiedEL)的擴(kuò)展。該語言支持設(shè)置和獲取屬性值,屬性分配和方法調(diào)用,訪問數(shù)組,集合和索引器的上下文,邏輯和算術(shù)運(yùn)算符,命名變量,并從Spring的IoC容器中按名稱檢索對(duì)象。它還支持列表預(yù)測(cè)和選擇以及常用列表聚合。
Data Access/Integration
數(shù)據(jù)訪問/集成層由JDBC,ORM,OXM,JMS和事務(wù)模塊(Transaction modules)組成。
- JDBC模塊提供了一個(gè)JDBC抽象層,它不需要進(jìn)行繁瑣的JDBC編碼和解析(parse)數(shù)據(jù)庫供應(yīng)商特定的錯(cuò)誤代碼。
- ORM模塊為流行的對(duì)象關(guān)系映射API提供了集成層,包括JPA,JDO和Hibernate。使用ORM包,你可以將所有這些O / R映射框架與Spring提供的所有其他功能結(jié)合使用,例如前面提到的簡單聲明式事務(wù)管理功能。
- OXM模塊提供了支持JAXB,Castor,XMLBeans,JiBX和XStream的對(duì)象/ XML映射實(shí)現(xiàn)的抽象層。
- Java消息傳遞服務(wù) (Java Messaging Service) 模塊包含用于生成和使用消息的功能。
- Transaction模塊支持編程和聲明式事務(wù)管理,用于實(shí)現(xiàn)特殊接口和所有POJO(普通Java對(duì)象, plain old Java objects)的類。
Web
Web層由Web,Web-Servlet,WebSocket和Web-Portlet模塊組成。
- Spring的Web模塊提供基本的面向Web的集成功能,如多部分文件上傳功能和使用servlet偵聽器的IoC容器的初始化以及面向Web的應(yīng)用程序上下文。它還包含Spring遠(yuǎn)程支持的Web相關(guān)部分。
- Web-Servlet模塊包含用于Web應(yīng)用程序的Spring MVC實(shí)現(xiàn)。Spring的MVC框架提供了域模型代碼和Web表單之間的清晰分離,并且與Spring框架的所有其他功能集成在一起。
- Web-Portlet模塊提供MVC實(shí)現(xiàn)以用于Portlet環(huán)境,并反映Web-Servlet模塊的功能。
AOP and Instrumention
Spring的AOP模塊提供了符合AOP聯(lián)盟的面向切面編程(aspect-oriented programming)實(shí)現(xiàn),允許你定義方法攔截器和切入點(diǎn),以便干凈地分離實(shí)現(xiàn)應(yīng)該分離的功能的代碼。使用源代碼級(jí)元數(shù)據(jù)(metadata)功能,你還可以將行為信息以類似于.NET屬性的方式整合到你的代碼中。
單獨(dú)的Aspects模塊提供了與AspectJ的集成。
Instrumentation模塊提供了用于某些應(yīng)用程序服務(wù)器的類工具支持和類加載器實(shí)現(xiàn)。
Test
測(cè)試模塊支持使用JUnit或TestNG測(cè)試Spring組件。它提供了一致的Spring ApplicationContexts加載和緩存這些上下文。它還提供了模擬對(duì)象,你可以使用它們單獨(dú)測(cè)試你的代碼。
Spring MVC 請(qǐng)求流程
Spring MVC 的整體請(qǐng)求流程如下:
- 用戶單擊某個(gè)請(qǐng)求路徑,發(fā)起一個(gè) request 請(qǐng)求,此請(qǐng)求會(huì)被前端控制器 (DispatcherServlet) 處理。
- 前端控制器 (DispatcherServlet) 請(qǐng)求處理映射器 (HandlerMapping) 去查找 Handler??梢砸罁?jù)注解或者 XML 配置去查找。
- 處理映射器 (HandlerMapping) 根據(jù)配置找到相應(yīng)的 Handler(可能包含若干個(gè) Interceptor 攔截器),返回給前端控制器 (DispatcherServlet)。
- 前端控制器 (DispatcherServlet) 請(qǐng)求處理器適配器 (HandlerAdapter) 去執(zhí)行相應(yīng)的 Handler(常稱為 Conroller)。
- 處理器適配器 (HandlerAdapter) 執(zhí)行 Handler。
- Handler 執(zhí)行完畢后會(huì)返回給處理器適配器 (HandlerAdapter) 一個(gè) ModelAndView 對(duì)象(Spring MVC 底層對(duì)象,包括 Model 數(shù)據(jù)模型和 View 試圖信息)。
- 處理器適配器 (HandlerAdapter) 接收到 Handler 返回的 ModelAndView 后,將其返回給前端控制器 (DispatcherServlet)。
- 前端控制器 (DispatcherServlet)接收到 ModelAndView 后,會(huì)請(qǐng)求視圖解析器 (View Resolver) 對(duì)視圖進(jìn)行解析。
- 視圖解析器 (View Resolver) 根據(jù) View 信息匹配到相應(yīng)的視圖結(jié)果,反饋給前端控制器 (DispatcherServlet) 。
- 前端控制器 (DispatcherServlet) 收到 View 具體視圖后,進(jìn)行視圖渲染,將 Model 中的模型數(shù)據(jù)填充到 View 視圖中的 request 域,生成最終的視圖 (View)。
- 前端控制器 (DispatcherServlet) 向用戶返回請(qǐng)求結(jié)果。
以上就是 Spring MVC 的整個(gè)請(qǐng)求處理流程,其中用到的組件有前端控制器 (DispatcherServlet) 、處理映射器 (HandlerMapping)、處理器適配器 (HandlerAdapter)、處理器 (Handler)、視圖解析器 (View Resolver)、視圖 (View)。
- 前端控制器 (DispatcherServlet):其作用是接收用戶請(qǐng)求,然后給用戶反饋結(jié)果。它的作用相當(dāng)于一個(gè)轉(zhuǎn)發(fā)器或中央處理器,控制整個(gè)流程的執(zhí)行,對(duì)各個(gè)組件進(jìn)行統(tǒng)一調(diào)度,以降低組件之間的耦合性,有利于組件之間的拓展。
- 處理映射器 (HandlerMapping):其作用是根據(jù)請(qǐng)求的 URL 路徑,通過注解或者 XML 配置,尋找匹配的處理器 (Handler) 信息。
- 處理器適配器 (HandlerAdapter):其作用是根據(jù)映射器找到的處理器 (Handler) 信息,按照特定規(guī)則執(zhí)行相關(guān)的處理器 (Handler)。
- 處理器 (Handler):其作用是執(zhí)行相關(guān)的請(qǐng)求處理邏輯,并返回相應(yīng)的數(shù)據(jù)和視圖信息,將其封裝至 ModelAndView 對(duì)象中。
- 視圖解析器 (View Resolver):其作用是進(jìn)行解析操作,通過 ModelAndView 對(duì)象中的 View 信息將邏輯視圖名解析成真正的視圖 View(如通過是個(gè) JSP 路徑返回一個(gè)真正的 JSP 頁面)。
- 視圖 (View):其本身是一個(gè)接口,實(shí)現(xiàn)類支持不同的 View 類型(JSP、FreeMarker、Excel等)。
上面的組件中,需要開發(fā)人員進(jìn)行開發(fā)的是處理器和視圖。一般來講,要開發(fā)處理該請(qǐng)求的具體代碼邏輯,以及最終展示給用戶的界面。
Spring MVC 與 Structs
Struts 與 Spring MVC 類似,也是一款基于傳統(tǒng) MVC 設(shè)計(jì)模式的 Java EE 框架。它的核心是一個(gè)彈性的控制層,能夠很好地發(fā)揮 MVC 模式的“分離顯示邏輯和業(yè)務(wù)邏輯”的能力。
Spring MVC 和 Struts 都是基于 MVC 模式的 Java EE 框架,而今年來越來越多的開發(fā)者使用 Spring MVC 技術(shù)來代替 Struts 技術(shù),那么相比于 Struts 框架,Spring MVC 的優(yōu)點(diǎn)在哪里呢?
區(qū)別一:Spring MVC基于方法開發(fā),Struts 基于類開發(fā)。
在使用 Spring MVC 框架開發(fā)時(shí),會(huì)將 URL 請(qǐng)求路徑與 Controller 類的某個(gè)方法進(jìn)行綁定,請(qǐng)求參數(shù)作為該方法的形參。當(dāng)用戶請(qǐng)求該 URL 路徑時(shí),Spring MVC 會(huì)將 URL 信息與 Controller 類的某個(gè)方法進(jìn)行映射,生成一個(gè) Handler 對(duì)象,該對(duì)象中只包含了一個(gè) method 方法。方法執(zhí)行結(jié)束之后,形參數(shù)據(jù)也會(huì)被銷毀。
而在使用 Struts 框架進(jìn)行開發(fā)時(shí),Action 類中所有方法使用的請(qǐng)求參數(shù)都是 Action 類中的成員變量,隨著方法變得越來越多,就很難分清楚 Action 中那么多的成員變量到底是給哪一個(gè)方法使用的,整個(gè) Action 類會(huì)變得十分混亂。
比較而言,Spring MVC 的優(yōu)點(diǎn)是,其所有請(qǐng)求參數(shù)都會(huì)被定義為相應(yīng)方法的形參,用戶在網(wǎng)頁上的請(qǐng)求路徑會(huì)被映射到 Controller 類對(duì)應(yīng)的方法上,此時(shí)請(qǐng)求參數(shù)會(huì)注入到對(duì)應(yīng)方法的形參上。Spring MVC 的這種方式類似于 Service 開發(fā)。
區(qū)別二:Spring MVC 可以進(jìn)行單例開發(fā),Struts 無法使用單例。
Spring MVC 支持單例開發(fā)模式,而 Struts 由于只能通過類的成員變量接受參數(shù),所以無法使用單例模式,只能使用多例。