1. 程式人生 > >spring三大框架整合

spring三大框架整合

   

Spring概述

Spring介紹

         Spring它是一個一站式的分層輕量級框架。

Spring體系結構 

        

1.      core container

a)        beans與core 它們提供spring框架最基本功能,包含ioc與di

b)        context 上下文物件,基於beans與cores

c)        spel它是sprng提供的一個表示式語言

2.      Data access/integration

a)        資料訪問

b)        整合

3.      Web

a)        Spring本身提供springmvc

b)        也可以與其它的web層進行整合

4.      AOP

AOP大部分情況下是使用動態代理來實現的。

5.      Test

使用spring可以方便的進行測試

 

Spring框架優點

n  方便解耦,簡化開發

Spring就是一個大工廠,可以將所有物件建立和依賴關係維護,交給Spring管理

n  AOP程式設計的支援

Spring提供面向切面程式設計,可以方便的實現對程式進行許可權攔截、執行監控等功能

n  宣告式事務的支援

只需要通過配置就可以完成對事務的管理,而無需手動程式設計

n  方便程式的測試

Spring對Junit4支援,可以通過註解方便的測試Spring程式

n  方便整合各種優秀框架

Spring不排斥各種優秀的開源框架,其內部提供了對各種優秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支援

n  降低JavaEE API的使用難度

Spring 對JavaEE開發中非常難用的一些API(JDBC、JavaMail、遠端呼叫等),都提供了封裝,使這些API應用難度大大降低

 

IOC與DI

Spring的jar包下載

Spring的官網:spring.io

我們課程中講解使用的是spring4.2.4

 

在spring3.0.2版本後,不在提供依賴jar包

 

docs 存在API和規範文件

libs 開發jar包

schema 開發過程中需要的xml的schema約束

spring開發環境搭建

在spring開發中,我們要根據不同的情況來匯入不同的jar包,當前我們要講解的是關於ioc與di

對於ioc與di講解我們只需要使用spring的核心功能。

1.      beans相關

2.      core相關

3.      context相關

4.      spel相關

 

我們使用spring框架也會使用到配置檔案,我們需要在src下建立一個關於spring的配置檔案,一般情況名稱叫applicationContext.xml

問題:applicationContext.xml約束?

        

         它的路徑:

spring-framework-4.2.4.RELEASE-dist\spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html

 

 

IOC快速入門

Ioc它是什麼,解決什麼問題,它的原理是如何實現。

IOC  inversion ofController 控制反轉。

在程式中所說的IOC其實簡單說,就是原來由我們自己例項化的物件交給spring容器來實始化。這時物件的實始化的權利就會反轉。

 

程式執行時報錯

 

原因:當前環境需要一個commons-loggin的jar包

 

總結spring使用步驟:

1.      在applicationContext.xml檔案中配置bean

 

2.      建立一個AppliCationContext物件

ApplicationContext它是BeanFactory的一個子介面,我們在使用時使用的是AppliCationContext的實現類ClassPathXmlApplicationContext

 

 

可以通過getBean(配置檔案中id名稱)來獲取指定的物件。

 

DI

         DI:dependencyinjection 依賴注入

                   在spring框架負責建立Bean物件時,動態將依賴物件注入到Bean元件。

        

 

 

簡單說,這時UserServiceImpl中的info屬性值就是ITCAST

 

面試題:IOC和DI區別?

         IOC控制反轉,是指物件例項化權利由spring容器來管理

         DI依賴注入 在spring建立物件的過程中,物件所依賴的屬性通過配置注入物件中。

 

Bean獲取與例項化

ApplicationContext與BeanFactory關係

 

ApplicationContext它是擴充套件BeanFactory介面。

BeanFactory它採取延遲載入的方案,只有真正在getBean時才會例項化Bean

 

在開發中我們一般使用的是ApplicationContext,真正使用的是其實現類,

FileSystemXmlAppliCationContext 根據檔案路徑獲取

ClassPathXmlApplicationContext  根據類路徑獲取

AppliCationContext它會在配置檔案載入時,就會初始化Bean,並且ApplicationContext它提供不同的應用層的Context實現。例如在web開發中可以使用WebApplicationContext.

 

Bean的例項化方式

無引數構造

對於這種方式,注意Bean類中必須提供無引數構造。

 

 

靜態工廠方法

需要建立一個工廠類,在工廠類中提供一個static返回bean物件的方法就可以。

 

 

例項工廠方法

需要建立一個工廠類,在工廠類中提供一個非static的建立bean物件的方法,在配置檔案中需要將工廠配置,還需要配置bean

 

 

Bean的作用域

 

在bean宣告時它有一個scope屬性,它是用於描述bean的作用域。

可取值有:

         singleton:單例 代表在spring ioc容器中只有一個Bean例項 (預設的scope)

         prototype多例 每一次從spring容器中獲取時,都會返回一個新的例項

         request用在web開發中,將bean物件request.setAttribute()儲存到request域中

         session用在web開發中,將bean物件session.setAttribute()儲存到session域中

 

在開如常用的值是singleton與prototype

 

Bean的生命週期

 

1.      instantiate bean物件例項化

2.      populate properties 封裝屬性

3.      如果Bean實現BeanNameAware執行setBeanName

4.      如果Bean實現BeanFactoryAwar或ApplicationContextAwar設定工廠setBeanFactory或上下文物件setApplicationContext

5.      如果存在類實現BeanPostProcessor(後處理Bean),執行postProcessBeforeInitialization

6.      如果Bean實現InitializingBean執行afterPropertiesSet

7.      呼叫自定義的init-method方法

8.      如果存在類實現BeanPostProcessor(處理Bean),執行postProcessAfterInitialization

9.      執行業務處理

10.  如果Bean實現DisposableBean執行destroy

11.  呼叫自定義的destroy-method

 

對於bean的生命週期方法:

第三步與第四步是讓Bean瞭解spring容器。

 

第五步與第八步可以針對指定的Bean進行功能增強,這時一般會使用動態代理.

 

第六步與第十步:通過實現指定的介面來完成init與destroy操作

但是在開發中一般不使用第6步與第10步,原因是我們可以使用第7步與第11步來完成。

第7步與第11步的初始化與銷燬操作它無耦合,推薦使用的。但是必須在配置檔案中指定初始化與銷燬的方法

 

 

總結:

         對於bean的生命週期,我們需要關注的主要有兩個方法:

1.      增強bean的功能可以使用後處理Bean, BeanPostProcessor

2.      如果需要初始化或銷燬操作我們可以使用init-method  destroy-method

 

注意:destroy-method只對scope=singleton有效果。

 

Bean的屬性注入

在spring中bean的屬性注入有兩種

構造器注入

 

Setter方法注入

 

關於ref屬性作用

 

使用ref來引入另一個bean物件,完成bean之間注入

 

集合屬性的注入

在spring中對於集合屬性,可以使用專門的標籤來完成注入例如:list   set  map properties等集合元素來完成集合屬性注入.

 

List屬性注入

 

如果屬性是陣列型別也可以使用list完成注入

Set屬性注入

 

 

Map屬性注入

 

 

Properties屬性注入

Java.util.Properties是java.utilsMap的實現類,它的key與value都是String型別.

 

 

名稱空間p和c的使用

Spring2.0以後提供了xml名稱空間。

 

P名稱空間

C名稱空間

首先它們不是真正的名稱空間,是虛擬的。它是嵌入到spring核心中的。

使用p名稱空間可以解決我們setter注入時<property>簡化

使用c名稱空間可以解決我們構造器注入時<constructor-arg>簡化

 

使用setter注入

在applicationContext.xml檔案中新增p名稱空間簡化setter注入

 

 

 

使用c名稱空間來解決構造器注入

 

在applicationContext.xml檔案中新增c名稱空間

 

 

 

 

注:如果c或p名稱空間操作的屬性字尾是”-ref”代表要引入另一個已經存在的bean,例如

 

SpEl

spring expression language  是在spring3.0以後的版本提供

它類似於ognl或el表示式,它可以提供在程式執行時構造複雜表示式來完成物件屬性儲存及方法呼叫等。

Spel表示式的格式  #{表示式}

 

示例1:完成bean之間的注入

 

示例2 支援屬性呼叫及方法呼叫 

 

 

Spring註解開發

在spring中使用註解,我們必須在applicationContext.xml檔案中新增一個標籤

<context:annotation-config/>作用是讓spring中常用的一些註解生效。

要使用contex名稱空間,必須在applicationContext.xml檔案中引入

 

完成bean註冊操作

@Component

 

 

測試時報錯

 

原因:如果你使用的是spring3.x那麼不會出現這個錯誤,如果使用的是spring4.x會報錯,原因是缺少jar包。

 

匯入jar後執行還有錯誤

 

我們在applicationContext.xml檔案中使用了一個標籤      <context:annotation-config/>,它代表的是可以使用spring的註解,但是我們在類上新增的註解,spring不知道位置。

要解決這個問題,我們可以使用<context:component-sacn base-package=””>

 

 

 

在spring2.5後為@Component添加了三個衍生的註解

@Rpository 用於DAO層

@Service 用於service層

@Controller 用於表現層

對於我們的bean所處在的位置可以選擇上述三個註解來應用,如果你的bean不明確位置,就可以使用@Component.

 

屬性依賴注入

1.      簡單的屬性注入

 

 

2.      複雜的屬性注入

 

 

注意:如果要掃描多個包下的註解可以寫成以下:

 

 

 

注意:@Value @Autowired它們可以修飾屬性,也可以修飾setter方法,如果寫在屬性上,就不需要提供setter方法。

 

 

@Autowired它預設是根據型別進行注入。

 

 

如果與@Qualifier一起使用,就可以根據名稱來進行注入。

我們也可以使用下面的方式來根據名稱進行屬性注入

 

 

其它註解

@Scope它以描述bean的作用域。

 

 

 

 

它相當於init-method=”myInit

 

它相當於是destroy-method=”myDestroy”

注意:對於銷燬的方法它只對bean的scope=singleton有效。

 

Spring在web開發中的應用

1.,在web專案中要使用spring需要匯入一個jar包

 

 

2.在web.xml檔案中配置Listener

        

這個ContextLoaderListener它實現了ServletContextListener

在這個listener中,當伺服器啟動時,將ApplicationContext物件,其實是它的一個實現類

WebApplicationContext,物件存入到了ServletContext中。

 

 

 

3.我們還需要在web.xml檔案中配置applicationContext.xml檔案的位置

         預設情況下會在WEB-INF目錄 下查詢applicationContext.xmls

         如果applicationContext.xml檔案不是在預設位置,我們可以在web.xml檔案中配置

        

Classpath:applicationContext.xml 它代表的是在當前工程的類路徑下(可以理解成是在src)下來查詢applicationContext.xml檔案。

contextConfigLocation它是在listener中宣告的一個常量,描述的就是spring配置檔案的位置。

 

Spring整合junit4測試

Spring整合junit4可以方便我們的測試。

 

1.      需要匯入一個spring-test.jar包

 

 

2.      可以在測試類上如下操作

 

 

 

Spring AOP

AOP概述

在軟體業,AOP為Aspect Oriented Programming的縮寫,意為:面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術。AOP是OOP的延續,是軟體開發中的一個熱點,也是Spring框架中的一個重要內容,是函數語言程式設計的一種衍生範型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。

AOP是一個概念,並沒有設定具體語言的實現,它能克服那些只有單繼承特性語言的缺點,spring2.0之後整合AspectJ第三方AOP技術。

AspectJ是一個面向切面的框架,它擴充套件了Java語言。AspectJ定義了AOP語法所以它有一個專門的編譯器用來生成遵守Java位元組編碼規範的Class檔案。

 

主要功能

日誌記錄,效能統計,安全控制,事務處理,異常處理等等

主要意圖

將日誌記錄,效能統計,安全控制,事務處理,異常處理等程式碼從業務邏輯程式碼中劃分出來,通過對這些行為的分離,我們希望可以將它們獨立到非指導業務邏輯的方法中,進而改變這些行為的時候不影響業務邏輯的程式碼。

 

AOP與OOP區別

OOP(面向物件程式設計)針對業務處理過程的實體及其屬性和行為進行抽象封裝,以獲得更加清晰高效的邏輯單元劃分。

而AOP則是針對業務處理過程中的切面進行提取,它所面對的是處理過程中的某個步驟或階段,以獲得邏輯過程中各部分之間低耦合性的隔離效果。這兩種設計思想在目標上有著本質的差異。

         換而言之,OOD/OOP面向名詞領域,AOP面向動詞領域。

 

AOP相關術語

目標物件target

指的是需要被增強的物件,由於spring aop是通過代理模式實現,從而這個物件永遠是被代理物件。

連線點(join point)

所謂連線點是指那些被攔截到的點,在spring中這些點指的是方法,因為spring只支援方法型別的連線點

切入點(pointcut)

表示一組 joint point,這些 joint point 或是通過邏輯關係組合起來,或是通過通配、正則表示式等方式集中起來,它定義了相應的 Advice 將要發生的地方

簡單說切入點是指我們要對哪些連線點進行攔截的定義

 

通知(advice)

所謂通知是指攔截到連線點之後所要做的事情就是通知,通知分為前置通知,後置通知,異常通知,最終通知,環繞通知

Advice 定義了在 pointcut 裡面定義的程式點具體要做的操作

引介introduction

引介是一種特殊的通知,在不修改類程式碼的前提下,introduction可以在執行期為類動態地新增一些方法或屬性

切面aspect

是切入點和通知的結合

織入weaving

織入是一個過程,是將切面應用到目標物件從而創建出AOP代理物件的過程,織入可以在編譯期,類裝載期,執行期進行。

Spring採用動態織入,而aspectj採用靜態織入

代理Proxy

一個類被AOP織入增強後,就產生一個結果代理類

 

AOP底層實現

AOP分為靜態AOP和動態AOP。靜態AOP是指AspectJ實現的AOP,他是將切面程式碼直接編譯到Java類檔案中。動態AOP是指將切面程式碼進行動態織入實現的AOP。Spring的AOP為動態AOP,實現的技術為: JDK提供的動態代理技術 和 CGLIB(動態位元組碼增強技術) 

JDK動態代理

在執行,在JVM內部動態生成class位元組碼物件(Class物件)

Jdk動態代理只針對於介面操作

 

 

第一個引數:目標類的類載入器物件

第二個引數:目標類的實現介面的Class[]

第三個引數:InvocationHandler它是一個介面,它的作用是是代理例項的呼叫處理程式實現的介面,介面中定義了一個方法

 

 

目標Target

 

 

代理工廠

 

CGLIB動態代理

CGLIB(Code Generation Library)是一個開源專案

是一個強大的,高效能,高質量的Code生成類庫,它可以在執行期擴充套件Java類與實現Java介面。CGLIB包的底層是通過使用一個小而快的位元組碼處理框架ASM,來轉換位元組碼並生成新的類

如果你要單獨使用CGLIB,那麼需要匯入cglib的jar包還需要一個asm相關jar包,但是spring框架的spring-core.jar包中已經集成了cglib與asm

 

注意:jdk的動態代理只可以為介面去完成操作,而cglib它可以為沒有實現介面的類去做代理,也可以為實現介面的類去做代理。

 

Cglib動態代理

 

setCallback傳遞的引數是Callback型別,我們使用的是MethodInterceptor

 

 

注意:cglib它可以為沒有實現介面的類做代理,也可以為介面類做代理.

 

問題:spring採用的是哪一種動態機制:

         如果目標物件,有介面,優先使用jdk動態代理

         如果目標物件,無介面,使用cglib動態代理。

 

Spring AOP程式設計

Spring的傳統aop程式設計

講解的目的是為了更好的理解aop。

在傳統的spring aop開發中它支援增強(advice)有五種:

1.      前置通知  目標方法執行前增強  org.springframework.aop.MethodBeforeAdvice

2.      後置通知  目標方法執行後增強 org.springframework.aop.AfterReturningAdvice

3.      環繞通知  目標方法執行前後進行增強  org.aopalliance.intercept.MethodInterceptor

4.      異常丟擲通知目標方法丟擲異常後的增強org.springframework.aop.ThrowsAdvice

5.      引介通知在目標類中新增一些新的方法或屬性(不講解)

org.springframework.aop.IntroductionInterceptor

 

經典的基於代理的AOP開發(瞭解)

基本的jar包

1.      bean

2.      core

3.      context

4.      expression

5.      aop

6.      需要aop聯盟的依賴jar包

 

第一步:編寫目標(target)

 

第二步增強(advice)

 

 

第三步在applicationContext.xml檔案中配置

 

第四測試

 

 

基於aspectJ切點傳統開發

第一步:在spring的配置檔案中定義目標與通知

 

第二步:使用<aop:xxx>標籤來完成切面與切點宣告

 

注意1:需要在xml配置檔案中匯入aop宣告

注意2:因為我們使用aspectj的切面宣告方式需要在匯入aspectj的jar包

 

傳統spring aop開發總結

第一步:編寫目標物件(target)

 

 

第二步:編寫通知(advice)

傳統的aop開發中,通知是需要實現指定介面。

 

 

第三步在配置檔案中配置切面(切面=切點+通知)

<aop:config>來宣告要對aop進行配置

<aop:pointcut>它是用於宣告切點(簡單說就是對哪些方法進行攔截)

<aop:advisor> 定義傳統的aop的切面,傳統的aop切面它只能包含一個切點與一個增強

<aop:aspect>定義aspectj框架的切面.,它可以包含多個切點與多個通知

 

關於切點表示式寫法

 

這個語法源於aspectJ的語法,spring中aop開發,對aspectj不是完全支援,只支援部分語法。

 

 

在開發中使用的比較多的是execution語法.

關於execution語法常用:

1.      execution(public * *()) 所有的public的方法

2.      execution(*cn.itheima.aop.*(..)) 所有的aop包下的所有類的方法(不包含子包)

3.      execution(*cn.itheima.aop..*(..)) 所有的aop包及其子包下的所有類的方法

4.      execution(*cn.itheima.aop.IOrderService.*(..)) IOrderService介面中定義的所有方法

5.      execution(*cn.itheima.aop.IOrderService+.*(..)) 匹配實現特定介面所有類的方法

6.      execution(* save*(..)) 區配所有的以save開頭的方法

Spring整合aspectj框架實現的aop

在現在的開發中使用這種方案比較多.

在spring2.0以後它支援jdk1.5註解,而整合aspectj後可以使用aspectj語法,可以簡化開發。

 

Aspect:切面 =切點+通知(多個切點與多個通知的組合)

AspectJ 它是一個第三方框架,spring從2.0後可以使用aspectJ框架的部分語法.

 

AspectJ框架它定義的通知型別有6種

1.      前置通知Before 相當於BeforeAdvice

2.      後置通知AfterReturning 相當於AfterReturningAdvice

3.      環繞通知 Around 相當於MethodInterceptor

4.      丟擲通知AfterThrowing 相當於ThrowAdvice

5.      引介通知DeclareParents 相當於IntroductionInterceptor

6.      最終通知After 不管是否異常,該通知都會執行

相比spring 的傳統AOP Advice多了一個最終通知

基於xml配置方案

第一步:建立目標(target)

 

第二步:建立通知(增強  advice)

注意:在aspectj中它的增強可以不實現任何介面,只需要定義出增強功能(方法)

 

 

第三步:在spring的xml 配置檔案中來配置

<aop:config>下的<aop:aspect>是aspectJ框架用來宣告切面的。

 

前置通知

 

後置通知

 

環繞通知

 

 

異常丟擲

 

注意:目標行為只有丟擲了異常後才會執行這個增強方法

 

最終通知

 

無論是否有異常,最終通知都會執行.

關於通知上的引數

1.      在前置通知上可以新增JoinPoint引數

通過它可以獲取目標相關的資訊

 

使用前置通知可以完成日誌記錄,許可權控制

 

2.      在後置通知上新增的引數

 

第二個引數val它可以獲取目標方法的返回值

注意:需要在配置檔案中配置

 

 

3.      環繞通知上的引數

 

它是我們開發中應用最多的,可以完成日誌操作,許可權操作,效能監控,事務管理

4.      丟擲異常通知上的引數

 

第二個引數Throwable它是用於接收丟擲的異常

注意:需要在配置檔案中宣告

 

5.      最終通知上的引數

 

可以使用最終通知完成資源釋放

關於代理方式選擇

在spring的aop開發中,它使用的是代理方案,代理實現有兩種:

1.      jdk的proxy

2.      cglib

spring框架預設情況下,會對有介面的類使用proxy代理。沒有介面的類使用cglib代理

 

Proxy-target-class的值預設是false,它代表有介面使用proxy代理

問題:如果現在對目標要使用cglib代理(不考慮是否有介面)?

只需要將proxy-target-class設定為true.

 

基於annotation方案

 第一步:編寫目標

 

 

在spring的配置檔案中配置掃描註解

 

 

第二步:編寫增強(advice)

 

使用@Aspect來宣告切面

使用@Before來宣告前置通知

注意:必須在spring的配置檔案中開啟aspectJ註解自動代理功能。

 

第三步:測試

 

其它通知型別及引數

後置通知

 

 

環繞通知

 

 

異常丟擲通知

 

 

最終通知

 

 

使用@Pointcut註解定義切點

在每一個通知中定義切點,工作量大,不方便維護,我們可以使用@Pointcut來宣告切點

 

 

切點允許邏輯運算例如mypointcut()||mypointcut1

 

關於代理方式選擇

 

Proxy-target-class預設值是false,代表的是如果目標是有介面的使用proxy代理,如果沒有介面使用cglib.

如果將proxy-target-class=true,不管目標是否有介面,都會使用cglib進行代理。

 

Spring jdbc Template

Spring提供了一個jdbc模板,它類似於dbutils工具。

 

 

問題:如何使用spring jdbc template?

第一:要匯入相關的jar包

        

         在這個基礎上我們還需要匯入

        

        

         還需要匯入相關的資料庫驅動jar包。

第二:spring jdbc template快速入門

快速入門

第一步:匯入相關jar包,建立了一個JdbcTemplateTest1測試類

 

第二步:建立庫與表

CREATEDATABASE springtest;

 

USEspringtest;

 

CREATETABLE t_user(

        

         id INT PRIMARY KEY AUTO_INCREMENT,

         NAME VARCHAR(20),

         age INT,

         sex VARCHAR(20)

)

 

INSERTINTO t_user VALUES(NULL,'tom',20,'男');

INSERTINTO t_user VALUES(NULL,'fox',30,'男');

INSERTINTO t_user VALUES(NULL,'tony',40,'男');

 

SELECT *FROM t_user;

 

第三步:編碼

 

 

配置spring內建的連線池DriverManagerDataSource

 

 

 

 

 

C3P0開源連線池配置

1.      匯入c3p0相關的jar包

 

 

2.      建立一個ComboPoolDataSource物件,設定相關的屬性

 

 

引入外部屬性檔案

Spring支援將經常修改屬性,在properties檔案中宣告,在xml配置檔案中引入外部的properties檔案的資訊。

 

在applicationContext.xml檔案中引入

 

在自己配置中需要從properties檔案中引入的資訊可以使用${name}方式來獲取

 

JdbcTemplate CRUD

執行insert update delete操作

 

只需要使用JdbcTemplate的update方法就可以執行insert update delete操作

 

 

 

 

執行select操作

簡單資料返回

 

 

 

 

複雜資料返回

 

注意:如果只返回一個domain物件,可以使用queryForObject方法,如果返回的是List<?>物件,可以使用query方法,但是都需要使用RowMapper來對ResultSet進行處理。

 

 

 

RowMapper它有一個實現類叫BeanPropertyRowMapper
如果使用BeanPropertyRowmapper,實體類必須提供一個無引數的public構造方法,類中的bean屬性名稱與表中的列要對應
注意:這個類是在spring2.5後提供。
 
     
 

Spring 事務管理

案例—轉賬操作

建立一個關於帳戶表

CREATETABLE account(

         id INT PRIMARY KEY AUTO_INCREMENT,

         NAME VARCHAR(20),

         money DOUBLE

)

 

INSERTINTO account VALUES(NULL,'tom',1000);

INSERTINTO account VALUES(NULL,'fox',1000);

建立service與dao

對於資料的操作使用spring jdbc template

 

 

 

關於service與dao的配置

 

我們讓dao去extends JdbcDaoSupport類,這個類中它建立了JdbcTempate,前提是我們需要注入一個dataSource.

 

 

在dao中在獲取JdbcTemplate可以使用父類提供的getJdbcTemplate方法來獲取。

 

轉賬操作的問題

 

如果在轉賬操作過程中出現問題,那麼轉賬會出現問題,結果如下

 

也就是我們程式需要事務控制。

 

Spring事務管理機制

Spring事務管理的四個優點:

1.      提供一致的對於不同的事務管理的API

2.      支援宣告式事務管理(重點)

3.      程式設計事務管理(在開發中應用比較少)

4.      優秀的整合與Spring的資料訪問

我們重點講解spring的事務管理的相關的API,還有宣告式事務管理

Spring事務管理主要提供了三個介面來完成

1.      org.springframework.transaction.PlatformTransactionManager

這是一個事務管理器,可以來選擇相關的平臺(jdbc  hibernate  jpa…)

2.      TransactionDefinition

它定義事務的一些相關資訊 例如 隔離 傳播 超時只讀

3.      TransactionStatus

它主要描述事務具體的執行狀態

 

PlatformTransactionManager

平臺事務管理器

在不同的持久化層解決技術它的事務程式碼不一樣。

JDBC開發

       Connection con=……;

       con.setAutoCommit(false);//開啟事務

       con.rollback();

       con.commit();

Hibernate開發

       Session session=….;

       Transactiont=session.beginTransaction();

       t.commit();

       t.rollback();

PlatformTransactionManager介面API

 

 

DataSourceTransactionManager 主要針對於JdbcTemplate開發  MyBatis開發

HibernateTransactionManasger主要針對於Hibernate開發

JpaTransactionManager 主要針對於JPA開發。

 

TransactionDefinition

它描述的是事務的定義資訊。

 

        

在TransactionDefinition中定義了大量的常量

隔離

以下是關於隔離性相關資訊

 

事務的四個特性 ACID  原子性 一致性 隔離性 永續性。

不考慮事務隔離性有什麼問題?

         髒讀,不可重複讀 虛讀。

ISOLATION_DEFUALT 它使用後端資料庫的預設隔離級別(spring中選項)

ISOLATION_READ_UNCOMMITTED 不能解決問題,會發生髒讀 不可重複讀 虛讀

ISOLATION_READ_COMMITTED 可以解決髒讀 會產生不可重複讀與虛讀。

ISOLATION_REPEATABLE_READ可以解決髒讀,不可重複讀解決不了虛讀

ISOLATION_SERIALIZABLE序列化,可以解決所有問題

對於不現的資料庫,它的底層預設事務隔離級別不一樣。

Oracle資料庫它預設的是read_committed

Mysql資料庫它預設的是repeatable_read.

 

超時

 

預設值是-1 它使用的是資料庫預設的超時時間。

 

只讀

         它的值有兩個true/false,如果選擇true一般是在select操作時

        

傳播

它解決的是兩個被事務管理的方法互相呼叫問題。它與資料庫沒關係,是程式內部維護的問題。

以下定義了事務的傳播行為

 

以上操作中最常用的三種:

PROPAGATION_REQUIRED 預設值 兩個操作處於同一個事務,如果之前沒有事務,新建一個事務

PROPAGATION_REQUIRES_NEW

兩個操作處於不同的事務

PROPAGATION_NESTED 它是一種巢狀事務,它是使用SavePoint來實現的。事務回滾時可以回滾到指定的savepoint,注意:它只對DataSourceTransactionManager有作用

 

以下了解

PROPAGATION_SUPPORTS 支援當前事務,如果不存在,就不使用事務

PROPAGATION_MANDATORY 支援當前事務,如果不存在,丟擲異常

PROPAGATION_NOT_SUPPORTED 以非事務執行,如果有事務存在,掛起當前事務

PROPAGATION_NEVER 以非事務執行,如果有事務存在,丟擲異常

 

TransactionStatus

它定義了事務狀態資訊,在事務執行過程中,得到某個時間點的狀態

 

 

宣告式事務管理

事務管理方式

1.      編碼方案不建議使用,它具有侵入性。在原有的業務程式碼基礎上去新增事務管理程式碼

2.      宣告式事務控制,基於AOP對目標進行代理,新增around環繞通知。

這種方案,它不具有侵入性,不需要修改原來的業務程式碼

 

基於xml配置宣告式事務管理方案

第一步:在applicationContext.xml檔案中新增aop與tx的名稱空間

 

第二步:在applicationContext.xml檔案中配置

         Spring提供的advice是傳統的springadvice

1.      宣告事務管理器

 

2.      配置通知

Spring為我們提供了一個TransactionInterceptor來完成增強

 

對於這個增強,我們可以使用spring為我們提供的一個標籤<tx:advice>來完成操作  

3.      配置切面

因為使用的是傳統的spring的advice,需要使用<aop:advisor>

 

基於annotation宣告式事務管理方案

可以使用@Transaction來在類或方法上新增宣告式事務管理

注意:需要在applicationContext.xml檔案中使用

 

相當於開啟註解事務控制

 

 

問題:關於xml方式與annotation方式的優缺點?

         從簡單上來說,使用註解更方便。

         使用配置的方案,可以對事務配置進行集中維護。

        

SSH框架整合

SSh=struts2+spring+hibernate 

struts2 2.3.24

spring 4.2.4

hibernate 5.0.7

關於xml配置檔案的整合方式

SSH整合jar包

Struts2框架需要jar包

 

Asm 是關於位元組碼操作

Commons-fileupload 關於檔案上傳

Commons-io 關於io流操作工具

Commons-lang 也是一個工具,包含了關於資料與字串操作

Freemaker 標籤庫模板檔案

Javassist 它也是關於位元組碼操作,動態代理可以使用它實現(類似於cglib)

Log4j關於日誌

Ognl 關於ognl表示式

Struts2-core  xwork-cor struts2框架底層是使用xwork

 

 

Struts2與spring整合還需要這個包

 

如果需要使用struts2提供的json處理

 

 

注意:如果使用註解方案,我們還需要匯入一個jar包

 

 

Hibernate框架需要的jar包

 

Antlr 語法解析包

Dom4j 解析xml

Geronimo-jta  apache geronimo它是一個開源javaEE伺服器 Geronimo-jta是這個開源專案提供jar包,在hibernate中是關於jta事務相關

Hibernate-commoins-annotations

這個包是我們在hibernate下來使用jpa相關的註解,這樣它不依賴於hibernate

Hibernate-core 開發hibernate必須

Hibernate-jpa 它是關於hibernate對jpa的支援

Jandex 用於索引annotation

Javassist 關於位元組碼操作(注意:strtus2中也引入這個jar包了)

Jboss-logging 它是關於jboss統一日誌處理

 

如果使用關於jpa相關操作需要匯入jpa依賴jar包

 

 

C3p0連線池

 

還需要資料庫相關的驅動jar包

 

 

還需要靜態日誌處理

 

Spring框架需要的jar包

Spring最基本jar包

 

 

AOP開發

 

 

Spring jdbc

 

Spring 事務管理需要tx

Spring整合hibernate

 

Spring整合web開發

 

如果使用到junit測試

 

 

還需要commons-loggin jar包

 

 

建立工程完成整合前期準備

需要的配置檔案:

Strtsu2框架   src/strtus.xml

Hibernate框架   src/hibernate.cfg.xml  在domain有 Xxx.hbm.xml

Spring框架   src/applicationContext.xml

關於日誌   log4j.properties

關於資料庫連線   db.properties

 

Spring整合hibernate

         基本原理:就是由spring來管理hibernate的SessionFactory

方式一:零障礙整合(瞭解)

         我們只需要使用spring中提供的一個LocalSessionFacotry來載入Hibernate的配置檔案。

        

 

Ssh-xml工程載入到伺服器後,如果可以自動建立表,就代表spring整合hibernate ok.

注意:我們必須配置spring的ContextLoaderListener

 

方式二(spring管理hibernate配置)

不在需要hibernate.cfg.xml檔案,所有關於hibernate.cfg.xml檔案中的配置都在spring的配置檔案中來配置。

 

首先要配置資料來源

 

接下來引入properties檔案

 

 

建立LocalSessionFactoryBean來完成spring管理hibernate中的SessionFactory

 

上述的props可以簡化成下面方案

 

 

載入hbm.xml配置檔案

 

mappingResources它類似於我們之前<mappingresource=””>

mappingLocations它載入時是根據類路徑載入classpath:路徑

 

mappingJarLocations它會載入jar檔案中的hbm.xml檔案

mappingDirectoryLocations 它載入的目錄

 

spring整合hibernate後的DAO

spring整合hiberante後,我們的dao只需要繼承HibernateDaoSupport類

在HibernateDaoSupport中只需要注入SessionFactory就可以獲得到HibernateTemplate,它是對hibernate操作的一個簡單封裝,可以讓我們方便使用原來hibernate的操作.

 

 

 

編寫service及測試

 

 

測試

 

事務管理

 

 

HibernateTemplate API介紹

儲存操作  session.save()

 

修改操作  session.update()

 

刪除操作  session.delete()

 

類似於session.saveOrUpdate()根據持久化物件的狀態來判斷執行save或update

 

獲取操作   get()  load()

 

 

 

Find操作  類似於session.createQuery().setParameter().list()

 

類似於hibernate中的QBC查詢,完全的面向物件方案

 

 

 

下面這個可以執行命名查詢

可以在User.hbm.xml檔案中定義hql或sql

 

 

 

 

Spring整合struts2框架

前期準備

建立一個addUser.jsp頁面

 

建立UserAction類

 

Struts.xml檔案中配置

 

 

Spring整合struts2原理分析

1.      spring整合struts2框架必須匯入一個jar包

struts2-spring-plugin.jar

 

2.      struts2框架