Spring

【內(nèi)容來源于網(wǎng)絡(luò)和書本,非原創(chuàng),系個(gè)人學(xué)習(xí)整理的筆記】

Spring

定義作用

Spring是一個(gè)開放源代碼的設(shè)計(jì)層面框架,他解決的是業(yè)務(wù)邏輯層和其他各層的松耦合問題,因此它將面向接口的編程思想貫穿整個(gè)系統(tǒng)應(yīng)用。

【eg結(jié)合hibernate和Struts】

Spring的基本組成完善的輕量級(jí)核心框架,通用的事務(wù)管理抽象層,JDBC抽象層,靈活的MVC Web應(yīng)用框架,AOP功能,集成了Toplink、Hibernate、 JDO等。

特點(diǎn)

輕量 控制反轉(zhuǎn) 面向切面 容器 框架

各模塊及作用

Spring 框架的分層架構(gòu),由 7 個(gè)定義良好的模塊組成。Spring 模塊構(gòu)建在核心容器之上,核心容器定義了創(chuàng)建、配置和管理 Bean 的方式

spring.png

組成Spring框架的每模塊(或組件)都可以單獨(dú)存在,也或以與其他一個(gè)或多個(gè)模塊聯(lián)合使用,這7個(gè)模塊的功能如下

① 核心容器。提供Spring框架的基本功能,其主要組件是BeanFactory,是工廠模式的實(shí)現(xiàn)。它通過控制反轉(zhuǎn)模式,將應(yīng)用程序配置和依賴性規(guī)范與實(shí)際應(yīng)用程序代碼分開。
② Spring 上下文。一個(gè)配置文件。向Spring 框架提供上下文信息,包括企業(yè)服務(wù),如JNDI、EJB、電子郵件、國際化、校驗(yàn)和調(diào)度等。
③ Spring AOP。通過配置管理特性,可以很容易地使 Spring 框架管理的任何對(duì)象支持AOP。Spring AOP 模塊直接將面向方面編程的功能集成到Spring框架中。
④ Spring DAO。JDBC DAO 抽象層提供了有用的異常層次結(jié)構(gòu),用來管理異常處理和不同數(shù)據(jù)庫供應(yīng)商拋出的錯(cuò)誤消息。
⑤ Spring ORM。Spring 框架插入了若干ORM框架,提供ORM的對(duì)象關(guān)系工具,其中包括JDO、Hibernate和iBatis SQL Map,并且都遵從Spring 的通用事務(wù)和 DAO 異常層次結(jié)構(gòu)。
⑥ Spring Web 模塊。為基于 Web 的應(yīng)用程序提供上下文。它建立在應(yīng)用程序上下文模塊之上,簡化了處理多份請(qǐng)求及將請(qǐng)求參數(shù)綁定到域?qū)ο蟮墓ぷ鳌?br> ⑦ Spring MVC 框架。一個(gè)全功能構(gòu)建Web應(yīng)用程序的 MVC 實(shí)現(xiàn)。通過策略接口實(shí)現(xiàn)高度可配置,MVC 容納了大量視圖技術(shù),其中包括JSP、Velocity、Tiles、iText和POI。

依賴注入

在軟件工程領(lǐng)域,依賴注入(Dependency Injection)是用于實(shí)現(xiàn)控制反轉(zhuǎn)(Inversion of Control)的最常見的方式之一。

控制反轉(zhuǎn)

控制反轉(zhuǎn)(Inversion of Control,簡稱IoC)是一個(gè)重要的面向?qū)ο缶幊痰姆▌t來削減計(jì)算機(jī)程序的耦合問題,也是輕量級(jí)的Spring框架的核心

IoC作為一種設(shè)計(jì)模式,可以徹底解決代碼耦合問題,它把耦合從代碼中移出去,放到統(tǒng)一的XML 文件中,通過一個(gè)容器在需要的時(shí)候把這個(gè)依賴關(guān)系形成,即把需要的接口實(shí)現(xiàn)注入到需要它的類中。

    Spring的依賴注入機(jī)制,可以在運(yùn)行期為組件配置所需資源,而無需在編寫組件代碼時(shí)就加以指定,大大降低了組件之間的耦合,實(shí)現(xiàn)了組件的即插即用。 

Spring的依賴注入對(duì)調(diào)用者和被調(diào)用者幾乎沒有任何要求,完全支持對(duì)POJO之間依賴關(guān)系的管理。

注入的三種模式

而要實(shí)現(xiàn)依賴注入則有三種形式:接口注入、setter方法注入和構(gòu)造方法注入。

1. 接口注入
接口注入就是將要注入的內(nèi)容轉(zhuǎn)入到一個(gè)接口中,然后將其注入到它的實(shí)現(xiàn)類中,因?yàn)閷?shí)現(xiàn)一個(gè)接口必須實(shí)現(xiàn)接口定義的所有方法。

2.setter方法注入
指注入者通過調(diào)用setter方法將一個(gè)對(duì)象注入進(jìn)去。這種注入方式簡單、直觀,因而在Spring的依賴注入里大量使用。

  1. 構(gòu)造方法注入
    構(gòu)造注入即是通過一個(gè)帶參的構(gòu)造函數(shù)將一個(gè)對(duì)象注入進(jìn)去。到目前為止,Spring支持setter方法注入與構(gòu)造注入兩種方式,它們可以同時(shí)存在

Spring核心接口

BeanFactory

在Spring中有幾種BeanFactory的實(shí)現(xiàn),其中最常使用的是org.springframework.bean.factory.xml.XmlBeanFactory。它根據(jù)XML文件中的定義裝載Bean。

這行簡單的代碼告訴Bean工廠從XML文件中讀取Bean的定義信息,但是現(xiàn)在Bean工廠沒有實(shí)例化Bean,Bean被延遲載入到Bean工廠中,就是說Bean工廠會(huì)立即把Bean定義信息載入進(jìn)來,但是Bean只有在需要的時(shí)候才被實(shí)例化。
為了從BeanFactory得到一個(gè)Bean,只要簡單地調(diào)用getBean()方法,把需要的Bean的名字當(dāng)作參數(shù)傳遞進(jìn)去就行了。由于得到的是Object類型,所以要進(jìn)行強(qiáng)制類型轉(zhuǎn)化。

ApplicationContext

表面上,ApplicationContext和BeanFactory差不多。兩者都是載入Bean定義信息,裝配Bean,根據(jù)需要分發(fā)Bean。但是ApplicationContext提供了更多功能:

ü(1)應(yīng)用上下文提供了文本信息解析工具,包括對(duì)國際化的支持。

ü(2)應(yīng)用上下文提供了載入文本資源的通用方法,如載入圖片。

ü(3)應(yīng)用上下文可以向注冊(cè)為監(jiān)聽器的Bean發(fā)送事件。

在ApplicationContext的諸多實(shí)現(xiàn)中,有三個(gè)常用的實(shí)現(xiàn):
(1)ClassPathXmlApplicationContext:從類路徑中的XML文件載入上下文定義信息,把上下文定義文件當(dāng)成類路徑資源。
(2)FileSystemXmlApplicationContext:從文件系統(tǒng)中的XML文件載入上下文定義信息。
(3)XmlWebApplicationContext:從Web系統(tǒng)中的XML文件載入上下文定義信息。

基本配置

使用xml裝配

<?xml version="1.0" encoding="UTF-8"?>
…
<beans …>                                     ?             // 根元素
    <bean id="foo" class="com.spring.Foo"/>     ?       // Bean實(shí)例
    <bean id="bar"class="com.spring.Bar"/>      ?     // Bean實(shí)例
</beans>

上下文定義文件的根元素<beans>有多個(gè)<bean>子元素,每個(gè)子元素定義了一個(gè)Bean(任何一個(gè)Java對(duì)象)如何被裝配到Spring容器中。

添加bean

在Spring中對(duì)一個(gè)Bean的最基本配置包括Bean的id和它的全稱類名。向Spring容器中添加一個(gè)Bean只需要向XML文件中添加一個(gè)<bean>子元素。例如下面的語句:

<bean id="foo" class="com.spring.Foo"/>

當(dāng)通過Spring容器創(chuàng)建一個(gè)Bean實(shí)例時(shí),不僅可以完成Bean的實(shí)例化,還可以為Bean指定特定的作用域。
(1)原型模式與單實(shí)例模式:Spring中的Bean缺省情況下是單實(shí)例模式。在容器分配Bean的時(shí)候,它總是返回同一個(gè)實(shí)例。但是,如果每次向ApplicationContext請(qǐng)求一個(gè)Bean的時(shí)候需要得到一個(gè)不同的實(shí)例,需要將Bean定義為原型模式。
<bean>的singleton屬性告訴ApplicationContext這個(gè)Bean是不是單實(shí)例Bean,缺省是true,如果把它設(shè)置為false就成了原型Bean。

(2)request或session:對(duì)于每次http請(qǐng)求或HttpSession,使用request或session定義的Bean都將產(chǎn)生一個(gè)新實(shí)例,即每次http請(qǐng)求或HttpSession將會(huì)產(chǎn)生不同的Bean實(shí)例。只有在Web應(yīng)用中使用Spring時(shí),該作用域有效。
(3)global session:每個(gè)全局的HttpSession對(duì)應(yīng)一個(gè)Bean實(shí)例。典型情況下,僅在使用portlet context的時(shí)候有效。只有在Web應(yīng)用中使用Spring時(shí),該作用域才有效。
在Bean的定義中設(shè)置自己的init-method,這個(gè)方法在Bean被實(shí)例化的時(shí)候馬上被調(diào)用。同樣,也可以設(shè)置自己的destroy-method,在Bean從容器中刪除之前調(diào)用。
一個(gè)典型的例子是連接池Bean。

AOP【結(jié)合實(shí)驗(yàn)】

定義

AOP(Aspect Oriented Programming,面向切面編程,簡稱AOP),也叫面向方面編程。AOP是軟件開發(fā)中的一個(gè)熱點(diǎn),也是Spring框架中的一個(gè)重要內(nèi)容。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率。

可以通過預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)在不修改源代碼的情況下給程序動(dòng)態(tài)統(tǒng)一添加功能的一種技術(shù)。

AOP將應(yīng)用系統(tǒng)分為兩部分,核心業(yè)務(wù)邏輯(Core business concerns)及橫向的通用邏輯,也就是所謂的切面。

? 使用AOP,你可以將處理Aspect的代碼注入主程序,通常主程序的主要目的并不在于處理這些Aspect。AOP可以防止代碼混亂。 Spring作為一種非侵略性的、輕型的AOP 框架,開發(fā)人員無需使用預(yù)編譯器或其他的元標(biāo)簽,便可以在Java程序中使用它。

橫切關(guān)注點(diǎn)的一個(gè)特點(diǎn)是,他們經(jīng)常發(fā)生在核心關(guān)注點(diǎn)的多處,而各處都基本相似。 **AOP的核心思想就是將應(yīng)用程序中的商業(yè)邏輯同對(duì)其提供支持的通用服務(wù)進(jìn)行分離。 **

Cross-cutting concern

在DynamicProxyDemo的例子中,記錄的動(dòng)作原先被橫切(Cross-cutting)到HelloSpeaker本身所負(fù)責(zé)的業(yè)務(wù)流程中。另外類似于日志這類的動(dòng)作,如安全檢查、事務(wù)等服務(wù),在一個(gè)應(yīng)用程序中常被安排到各個(gè)類的處理流程之中。這些動(dòng)作在AOP的術(shù)語中被稱為Cross-cutting concern。如圖7.8所示,原來的業(yè)務(wù)流程是很單純的。

Aspect

將散落在各個(gè)業(yè)務(wù)類中的Cross-cutting concerns收集起來,設(shè)計(jì)各個(gè)獨(dú)立可重用的類,這種類稱之為Aspect。例如在動(dòng)態(tài)代理中將日志的動(dòng)作設(shè)計(jì)為一個(gè)LogHandler類,LogHandler類在AOP術(shù)語中就是Aspect的一個(gè)具體實(shí)例。在需要該服務(wù)的時(shí)候,縫合到應(yīng)用程序中;不需要服務(wù)的時(shí)候,也可以馬上從應(yīng)用程序中脫離。應(yīng)用程序中的可重用組件不用做任何的修改。例如,在動(dòng)態(tài)代理中的HelloSpeaker所代表的角色就是應(yīng)用程序中可重用的組件,在它需要日志服務(wù)時(shí)并不用修改本身的程序代碼

相關(guān)名詞

AOP有一些重要概念需要理解,包括以下方面:
連接點(diǎn)(Joinpoint):程序執(zhí)行過程中明確的點(diǎn)。
切入點(diǎn)(Pointcut):指定一個(gè)通知將被引發(fā)的一系列連接點(diǎn)的集合。
增強(qiáng)(Advice):在特定的連接點(diǎn),AOP框架執(zhí)行的動(dòng)作。。
目標(biāo)對(duì)象(Target):包含連接點(diǎn)的對(duì)象,也被稱作被增強(qiáng)或被代理對(duì)象。
引入(Introduction):添加方法或字段到被增強(qiáng)的類。Spring允許引入新的接口到任何被增強(qiáng)的對(duì)象。
織入(Weaving):織入是將增強(qiáng)添加對(duì)目標(biāo)類具體連接點(diǎn)上的過程。
代理(Proxy):AOP框架創(chuàng)建的對(duì)象,包含增強(qiáng)。
切面(Aspect):切面由切入點(diǎn)和增強(qiáng)組成。
各種通知類型又包括:
Around通知:環(huán)繞通知,包圍一個(gè)連接點(diǎn)的通知。
Before通知:在一個(gè)連接點(diǎn)之前執(zhí)行的通知。
Throws通知:在方法拋出異常時(shí)執(zhí)行的通知。。
After returning通知:在連接點(diǎn)正常完成后執(zhí)行的通知。
Around通知是最通用的通知類型。

實(shí)現(xiàn)AOP的技術(shù)

實(shí)現(xiàn)AOP的技術(shù),主要分為兩大類:

  • 采用靜態(tài)織入的方式,引入特定的語法創(chuàng)建“方面”,從而使得編譯器可以在編譯期間織入有關(guān)“方面”的代碼。在代碼的編譯階段植入Pointcut的內(nèi)容,優(yōu)點(diǎn)是性能好,但靈活性不夠;
  • 采用動(dòng)態(tài)代理技術(shù),利用截取消息的方式,對(duì)該消息進(jìn)行裝飾,以取代原有對(duì)象行為的執(zhí)行;在代碼執(zhí)行階段,在內(nèi)存中截獲對(duì)象,動(dòng)態(tài)的插入Pointcut的內(nèi)容,優(yōu)點(diǎn)是不需要額外的編譯,但是性能比靜態(tài)織入要低。

靜態(tài)代理 & 動(dòng)態(tài)代理

通知Advice

Spring提供了5種通知(Advice)類型:Interception Around、Before、After Returning、Throw 和Introduction。它們分別在以下情況被調(diào)用:
1 Interception Around Advice:在目標(biāo)對(duì)象的方法執(zhí)行前后被調(diào)用。
2 Before Advice:在目標(biāo)對(duì)象的方法執(zhí)行前被調(diào)用。
3 After Returning Advice:在目標(biāo)對(duì)象的方法執(zhí)行后被調(diào)用。
4 Throw Advice:在目標(biāo)對(duì)象的方法拋出異常時(shí)被調(diào)用。
5 Introduction Advice:一種特殊類型的攔截通知,只有在目標(biāo)對(duì)象的方法調(diào)用完畢后執(zhí)行。

Spring 事務(wù)

Spring 的事務(wù)處理,可以說是 Spring AOP 的一種實(shí)現(xiàn)。因?yàn)槭聞?wù)處理是所謂方面(Aspect)的一個(gè)子集。因此默認(rèn)情況下,事務(wù)處理是利用 Java 動(dòng)態(tài)代理機(jī)制實(shí)現(xiàn)的,這樣就必須先定義一個(gè)接口,然后再編寫實(shí)現(xiàn);而對(duì)于沒有接口的 Javabean ,則通過 CGLIB 實(shí)現(xiàn)。這部分是Spring AOP 部分的內(nèi)容。

四種方式

1.采用TransactionProxyFactoryBean為目標(biāo)bean生成事務(wù)代理的配置。此方式是最傳統(tǒng)、配置文件最臃腫、最難以閱讀的方式。
2.采用bean繼承的事務(wù)代理配置方式,比較簡潔,但依然是增量式配置。
3.采用BeanNameAutoProxyCreator,根據(jù)bean name自動(dòng)生成事務(wù)代理的方式,這是直接利用Spring的AOP框架配置事務(wù)代理的方式,需要對(duì)Spring的AOP框架有所理解。但這種方式避免了增量式配置,效果非常不錯(cuò)。
4.采用DefaultAdvisorAutoProxyCreator,這也是直接利用Spring的AOP框架配置事務(wù)代理的方式,效果也非常不錯(cuò),只是這種配置方式的可讀性不如第三種方式。

Spring與Struts的整合

在這種組合中Struts 2依然充當(dāng)著視圖層和控制層角色,但是控制層不直接調(diào)用模型層中的業(yè)務(wù)邏輯層,而是在中間加了一個(gè)Spring,采用控制反轉(zhuǎn)的方式進(jìn)行松耦合??蚣苋鐖D所示。

spring + Struts.png

Spring 與 Hibernate整合

Spring與Struts一樣具有V層和C層的能力,即視圖與控制器能力。在Spring+Hibernate方式的組合中,Spring最重要的角色還是視圖和控制,盡管它的控制反轉(zhuǎn)機(jī)制也發(fā)揮了作用,架構(gòu)如圖7.14所示。

Spring+hibernate.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容