05、源碼分析-純手寫數(shù)據(jù)庫連接池spring框架_第1頁
05、源碼分析-純手寫數(shù)據(jù)庫連接池spring框架_第2頁
05、源碼分析-純手寫數(shù)據(jù)庫連接池spring框架_第3頁
05、源碼分析-純手寫數(shù)據(jù)庫連接池spring框架_第4頁
05、源碼分析-純手寫數(shù)據(jù)庫連接池spring框架_第5頁
已閱讀5頁,還剩46頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、知識(shí)SpringSpring 是一個(gè)開源框架,Spring 是于 2003 年興起的一個(gè)輕量級(jí)的 Java 開發(fā)框架,由 Rod Johnson 在其著作 Expert One-On-One J2EE Development and Design 中闡述的部分理念和原型衍生而來。它是為了解決企業(yè)應(yīng)用開發(fā)的復(fù)雜性而創(chuàng)建的??蚣艿闹饕獌?yōu)勢(shì)之一就是其分層架構(gòu),分層架構(gòu)允許使用者選擇使用哪一個(gè)組件,同時(shí)為 J2EE 應(yīng)用程序開發(fā)提供集成的框架。Spring 使用基本的 JavaBean 來完成以前只可能由EJB 完成的事情。然而,Spring 的用途不僅限于服務(wù)器端的開發(fā)。從簡(jiǎn)單性、可測(cè)試性和松耦合的

2、角度而言,任何 Java 應(yīng)用都可以從 Spring 中受益。Spring 的是控制反轉(zhuǎn)(IoC)和面向切面(AOP)。簡(jiǎn)單來說,Spring 是一個(gè)分層的 JavaSE/EEfull-stack(一站式)輕量級(jí)開源框架。為什么說 Spring 是一個(gè)一站式的輕量級(jí)開源框架呢?EE 開發(fā)可分成三層架構(gòu),針對(duì) JavaEE 的三層結(jié)構(gòu),每一層 Spring 都提供了不同的解決技術(shù)。WEB 層:SpringMVC業(yè)務(wù)層:Spring 的 IoC持久層:Spring 的 JDBCTemplate(Spring 的 JDBC 模板,ORM 模板用于整合其他的持久層框架)從上面的簡(jiǎn)要介紹中,我們要知道

3、Spring 的有兩部分:IoC:控制反轉(zhuǎn)。舉例來說,在之前的操作中,比方說有一個(gè)類,我們想要調(diào)用類里面的方法(不是靜態(tài)方法),就要?jiǎng)?chuàng)建類的對(duì)象,使用對(duì)象調(diào)用方法實(shí)現(xiàn)。對(duì)于 Spring 來說,Spring 創(chuàng)建對(duì)象的過程,不是在代碼里面實(shí)現(xiàn)的,而是交給 Spring 來進(jìn)行配置實(shí)現(xiàn)的。AOP:面向切面編程。SpringAOP 原理AOP 編程技術(shù)什么是 AOP 編程AOP: Aspect Oriented Programming 面向切面編程。面向切面編程(也叫面向方面):Aspect Oriented Programming(AOP),是目前軟件開發(fā)中的一個(gè)熱點(diǎn)。利用 AOP 可以對(duì)業(yè)務(wù)邏

4、輯的各個(gè)部分進(jìn)行,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率。AOP 是 OOP 的延續(xù),是(Aspect Oriented Programming)的縮寫,意思是面向切面(方面)編程。主要的功能是:日志,性能統(tǒng)計(jì),安全控制,事務(wù)處理,異常處理等等。主要的意圖是:將日志,性能統(tǒng)計(jì),安全控制,事務(wù)處理,異常處理等代碼從業(yè)務(wù)邏輯代碼中劃分出來,通過對(duì)這些行為的分離,我們希望可以將它們行為的時(shí)候不影響業(yè)務(wù)邏輯的代碼。到非指導(dǎo)業(yè)務(wù)邏輯的方法中,進(jìn)而改 變這些可以通過預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)實(shí)現(xiàn)在不修改源代碼的情況下給程序動(dòng)態(tài)統(tǒng)一添加功能的一種技術(shù)。AOP 實(shí)際是 G

5、oF 設(shè)計(jì)模式的延續(xù),設(shè)計(jì)模式孜孜不倦追求的是調(diào)用者和被調(diào)用者之間的解耦,AOP 可以說也是這種目標(biāo)的一種實(shí)現(xiàn)。假設(shè)把應(yīng)用程序想成一個(gè)立體結(jié)構(gòu)的話,OOP 的利刃是縱向切入系統(tǒng),把系統(tǒng)劃分為很多個(gè)模塊(如:用戶模塊,文章模塊等等),而 AOP 的利刃是橫向切入系統(tǒng),提取各個(gè)模塊可能都要重復(fù)操作的部分(如:權(quán)限檢查,日志等等)。由此可見,AOP 是 OOP 的一個(gè)有效補(bǔ)充。注意:AOP 不是一種技術(shù),實(shí)際上是編程思想。凡是符合 AOP 思想的技術(shù),都可以看成是 AOP 的實(shí)現(xiàn)。Aop, aspect object programming 面向切面編程功能: 讓關(guān)注點(diǎn)代碼與業(yè)務(wù)代碼分離!關(guān)注點(diǎn)關(guān)注

6、點(diǎn),重復(fù)代碼就叫做關(guān)注點(diǎn);切面關(guān)注點(diǎn)形成的類,就叫切面(類)!面向切面編程,就是指 對(duì)很多功能都有的重復(fù)的代碼抽取,再在運(yùn)行的時(shí)候網(wǎng)業(yè)務(wù)方法上動(dòng)態(tài)植入“切面類代碼”。切入點(diǎn)執(zhí)行目標(biāo)對(duì)象方法,動(dòng)態(tài)植入切面代碼??梢酝ㄟ^切入點(diǎn)表達(dá)式,指定哪些類的哪些方法; 給指定的類在運(yùn)行的時(shí)候植入切面類代碼。AOP 底層實(shí)現(xiàn)原理設(shè)計(jì)模式什么是模式通過控制對(duì)象的,可以詳細(xì)某個(gè)對(duì)象的方法,在這個(gè)方法調(diào)用處理,或調(diào)用后處理。既(AOP 微實(shí)現(xiàn)),AOP技術(shù)面向切面編程。模式應(yīng)用場(chǎng)景SpringAOP、事物原理、日志打印、權(quán)限控制、調(diào)用、安全可以隱蔽真實(shí)的分類靜態(tài)(靜態(tài)定義類)動(dòng)態(tài)(動(dòng)態(tài)生成類)Jdk 自帶動(dòng)態(tài)Cgli

7、b 、javaassist(字節(jié)碼操作庫)靜態(tài)什么是靜態(tài)由程序員創(chuàng)建或工具生成類的源碼,再編譯類。所謂靜態(tài)也就是在程序運(yùn)行前就已經(jīng)存在類的字節(jié)碼文件,類和委托類的關(guān)系在運(yùn)行前就確定了。靜態(tài)代碼動(dòng)態(tài)什么是動(dòng)態(tài)1.對(duì)象,不需要實(shí)現(xiàn)接口2.對(duì)象的生成,是利用 JDK 的 API,動(dòng)態(tài)的在內(nèi)存中構(gòu)建對(duì)象(需要我們指定創(chuàng)建對(duì)象/目標(biāo)對(duì)象實(shí)現(xiàn)的接口的類型)3.動(dòng)態(tài)也叫做:JDK,接口JDK 動(dòng)態(tài)1)原理:是根據(jù)類加載器和接口創(chuàng)建類(此類是接口的實(shí)現(xiàn)類,所以必須使用接口 面向接口生成,位于 java.lang.reflect 包下)2)實(shí)現(xiàn)方式:1. 通過實(shí)現(xiàn) InvocationHandler 接口創(chuàng)建自

8、己的調(diào)用處理器 IvocationHandler handler = new InvocationHandlerImpl();2. 通過為 Proxy 類指定 ClassLoader 對(duì)象和一組 interface 創(chuàng)建動(dòng)態(tài)類 Class clazz = Proxy.getProxyClass(classLoader,new Class);3. 通過反射機(jī)制獲取動(dòng)態(tài)類的構(gòu)造函數(shù),其參數(shù)類型是調(diào)用處理器接口類型 Constructor constructor = clazz.getConstructor(newClassInvocationHandler.class);4. 通過構(gòu)造函數(shù)創(chuàng)建類實(shí)

9、例,此時(shí)需將調(diào)用處理器對(duì)象作為參數(shù)被傳入 Interface Proxy = (Interface)constructor.newInstance(newpublic interface IUserDao void save();public class UserDao implements IUserDao public void save() System.out.println("已經(jīng)保存數(shù)據(jù).");類public class UserDaoProxy implements IUserDao private IUserDao target;public UserDao

10、Proxy(IUserDao iuserDao) this.target = iuserDao;public void save() System.out.println("開啟事物."); target.save(); System.out.println("關(guān)閉事物.");Object (handler);缺點(diǎn):jdk 動(dòng)態(tài),必須是面向接口,目標(biāo)業(yè)務(wù)類必須實(shí)現(xiàn)接口CGLIB 動(dòng)態(tài)原理:利用 asm 開源包,對(duì)對(duì)象類的 class 文件加載進(jìn)來,通過修改其字節(jié)碼生成子類來處理。什么是 CGLIB 動(dòng)態(tài)使用 cglibCode Generation Li

11、brary實(shí)現(xiàn)動(dòng)態(tài),并不要求委托類必須實(shí)現(xiàn)接口,底層采用 asm 字節(jié)碼生成框架生成類的字節(jié)碼CGLIB 動(dòng)態(tài)相關(guān)代碼/ 每次生成動(dòng)態(tài)類對(duì)象時(shí),實(shí)現(xiàn)了InvocationHandler接口的調(diào)用處理器對(duì)象public class InvocationHandlerImpl implements InvocationHandler private Object target;/ 這其實(shí)業(yè)務(wù)實(shí)現(xiàn)類對(duì)象,用來調(diào)用具體的業(yè)務(wù)方法/ 通過構(gòu)造函數(shù)傳入目標(biāo)對(duì)象public InvocationHandlerImpl(Object target) this.target = target;public Ob

12、ject invoke(Object proxy, Method method, Object args) throws Throwable Object result = null;System.out.println("調(diào)用開始處理");result = method.invoke(target, args); System.out.println("調(diào)用結(jié)束處理"); return result;public static void main(String args) throws NoSuchMethodException, SecurityEx

13、ception, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException / 被對(duì)象IUserDao userDao = new UserDao();InvocationHandlerImpl invocationHandlerImpl = new InvocationHandlerImpl(userDao); ClassLoader loader = userDao.getClass().getClassLoader();Class<?>

14、 interfaces = userDao.getClass().getInterfaces();/ 主要裝載器、一組接口及調(diào)用處理動(dòng)態(tài)實(shí)例IUserDao newProxyInstance = (IUserDao) Proxy.newProxyInstance(loader, interfaces, invocationHandlerImpl); newProxyInstance.save();CGLIB 動(dòng)態(tài)與 JDK 動(dòng)態(tài)區(qū)別java 動(dòng)態(tài)是利用反射機(jī)制生成一個(gè)實(shí)現(xiàn)接口的類,在調(diào)用具體方法前調(diào)用 InvokeHandler 來處理。而 cglib 動(dòng)態(tài)是利用 asm 開源包,對(duì)對(duì)象類的

15、class 文件加載進(jìn)來,通過修改其字節(jié)碼生成子類來處理。Spring 中。1、如果目標(biāo)對(duì)象實(shí)現(xiàn)了接口,默認(rèn)情況下會(huì)采用 JDK 的動(dòng)態(tài)實(shí)現(xiàn) AOP2、如果目標(biāo)對(duì)象實(shí)現(xiàn)了接口,可以強(qiáng)制使用 CGLIB 實(shí)現(xiàn) AOP3、如果目標(biāo)對(duì)象沒有實(shí)現(xiàn)了接口,必須采用 CGLIB 庫,spring 會(huì)自動(dòng)在 JDK 動(dòng)態(tài)和 CGLIB 之間轉(zhuǎn)換JDK 動(dòng)態(tài)只能對(duì)實(shí)現(xiàn)了接口的類生成,而不能針對(duì)類 。CGLIB 是針對(duì)類實(shí)現(xiàn),主要是對(duì)指定的類生成一個(gè)子類,覆蓋其中的方法 。因?yàn)槭抢^承,所以該類或方法最好不要成 final ,final 可以繼承和多態(tài)。public class CglibProxy implem

16、ents MethodInterceptor private Object targetObject;/ 這里的目標(biāo)類型為Object,則可以接受任意一種參數(shù)作為被類,實(shí)現(xiàn)了動(dòng)態(tài)public Object getInstance(Object target) / 設(shè)置需要?jiǎng)?chuàng)建子類的類this.targetObject = target; Enhancer enhancer = new Enhancer();enhancer.setSuperclass(target.getClass(); enhancer.setCallback(this);return enhancer.create();p

17、ublic Object intercept(Object obj, Method method, Object args, MethodProxy proxy) throws Throwable System.out.println("開啟事物");Object result = proxy.invoke(targetObject, args);System.out.println("關(guān)閉事物");/ 返回對(duì)象return result;public static void main(String args) CglibProxy cglibProxy

18、 = new CglibProxy();UserDao userDao = (UserDao) cglibProxy.getInstance(new UserDao(); userDao.save();AOP 編程使用注解版本實(shí)現(xiàn) AOP<aop:aspectj-autoproxy></aop:aspectj-autoproxy> 開啟事物注解權(quán)限Aspect指定一個(gè)類為切面類Pointcut("execution(* com.itmayiedu.service.UserService.add(.)") 指定切入點(diǎn)表達(dá)式Before("po

19、intCut_()")前置通知: 目標(biāo)方法之前執(zhí)行After("pointCut_()")后置通知:目標(biāo)方法之后執(zhí)行(始終執(zhí)行) AfterReturning("pointCut_()")返回后通知: 執(zhí)行方法結(jié)束前執(zhí)行(異常不執(zhí)行) AfterThrowing("pointCut_()")異常通知: 出現(xiàn)異常時(shí)候執(zhí)行Around("pointCut_()")環(huán)繞通知: 環(huán)繞目標(biāo)方法執(zhí)行Component Aspectpublic class AopLog / 前置通知Before("execu

20、tion(* com.itmayiedu.service.UserService.add(.)")public void begin() System.out.println("前置通知");/ 后置通知After("execution(* com.itmayiedu.service.UserService.add(.)")public void commit() System.out.println("后置通知");/ 運(yùn)行通知AfterReturning("execution(* com.itmayiedu.s

21、ervice.UserService.add(.)")public void returning() System.out.println("運(yùn)行通知");/ 異常通知AfterThrowing("execution(* com.itmayiedu.service.UserService.add(.)")public void afterThrowing() System.out.println("異常通知");XML 方式實(shí)現(xiàn) AOPXml 實(shí)現(xiàn) aop 編程:1) 引入 jar 文件 【aop 相關(guān) jar, 4 個(gè)】2

22、) 引入 aop 名稱空間3) aop 配置* 配置切面類 (重復(fù)執(zhí)行代碼形成的類)* aop 配置哪些方法 /到方法后應(yīng)用通知代碼<beans xmlns=""xmlns:xsi=""xmlns:p=""xmlns:context=""xmlns:aop=""xsi:schemaLocation=""><!- dao 實(shí)例 -><bean id="userService" class="com.itmayiedu.

23、service.UserService"></bean><!- 切面類 ->/ 環(huán)繞通知Around("execution(* com.itmayiedu.service.UserService.add(.)")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable System.out.println("環(huán)繞通知開始");proceedingJoinPceed();System.out.println

24、("環(huán)繞通知結(jié)束");<bean id="aop" class="com.itmayiedu.aop2.AopLog2"></bean><!- Aop配置 -><aop:config><!- 定義一個(gè)切入點(diǎn)表達(dá)式:哪些方法 -><aop:pointcut expression="execution(* com.itmayiedu.service.UserService.*(.)"id="pt" /><!- 切面 -&g

25、t;<aop:aspect ref="aop"><!- 環(huán)繞通知 -><aop:around method="around" pointcut-ref="pt" /><!- 前置通知: 在目標(biāo)方法調(diào)用前執(zhí)行 -><aop:before method="begin" pointcut-ref="pt" /><!- 后置通知: -><aop:after method="after" pointcut-r

26、ef="pt" /><!- 返回后通知 -><aop:after-returning method="afterReturning" pointcut-ref="pt" /><!- 異常通知 -><aop:after-throwing method="afterThrowing" pointcut-ref="pt" /></aop:aspect></aop:config></beans>public cla

27、ss AopLog2 / 前置通知public void begin() System.out.println("前置通知");/ 后置通知public void commit() System.out.println("后置通知");/ 運(yùn)行通知public void returning() System.out.println("運(yùn)行通知");/ 異常通知public void afterThrowing() AOP 編程應(yīng)用場(chǎng)景日志,性能統(tǒng)計(jì),安全控制,事務(wù)處理,異常處理Spring 事務(wù)使用事務(wù)基本特性 原子性(Atomici

28、ty)原子性是指事務(wù)包含的所有操作要么全部成功,要么全部失敗回滾,因此事務(wù)的操作如果成功就必須要完全應(yīng)用到數(shù)據(jù)庫,如果操作失敗則不能對(duì)數(shù)據(jù)庫有任何影響。 一致性(Consistency)一致性是指事務(wù)必須使數(shù)據(jù)庫從一個(gè)一致性狀態(tài)變換到另一個(gè)一致性狀態(tài),也就是說一個(gè)事務(wù)執(zhí)行之前和執(zhí)行之后都必須處于一致性狀態(tài)。拿轉(zhuǎn)賬來說,假設(shè)用戶A 和用戶B 兩者的錢加起來一共是 5000,那么不管 A 和 B 之間如何轉(zhuǎn)賬,轉(zhuǎn)幾次賬,事務(wù)結(jié)束后兩個(gè)用戶的錢相加起來應(yīng)該還得是 5000,這就是事務(wù)的一致性。性(Isolation)性是當(dāng)多個(gè)用戶并發(fā)數(shù)據(jù)庫時(shí),比如操作同一張表時(shí),數(shù)據(jù)庫為每一個(gè)用戶開啟的事務(wù),不Sy

29、stem.out.println("異常通知");/ 環(huán)繞通知public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable System.out.println("環(huán)繞通知開始");proceedingJoinPceed();System.out.println("環(huán)繞通知結(jié)束");能被其他事務(wù)的操作所干擾,多個(gè)并發(fā)事務(wù)之間要相互。即要達(dá)到這么一種效果:對(duì)于任意兩個(gè)并發(fā)的事務(wù) T1 和 T2,在事務(wù) T1 看來,T2 要么在 T

30、1 開始之前就已經(jīng)結(jié)束,要么在 T1 結(jié)束之后才開始,這樣每個(gè)事務(wù)都感覺不到有其他事務(wù)在并發(fā)地執(zhí)行。關(guān)于事務(wù)的性數(shù)據(jù)庫提供了多種級(jí)別,稍后會(huì)介紹到。 持久性(Durability)持久性是指一個(gè)事務(wù)一旦被提交了,那么對(duì)數(shù)據(jù)庫中的數(shù)據(jù)的改變就是性的,即便是在數(shù)據(jù)庫系統(tǒng)遇到故障的情況下也丟失提交事務(wù)的操作。例如我們?cè)谑褂?JDBC 操作數(shù)據(jù)庫時(shí),在提交事務(wù)方法后,提示用戶事務(wù)操作完成,當(dāng)我們程序執(zhí)行完成直到看到提示后,就可以認(rèn)定事務(wù)以及正確提交,即使這時(shí)候數(shù)據(jù)庫出現(xiàn)了問題,也必須要將我們的事務(wù)完全執(zhí)行完成,否則就會(huì)造成我們看到提示事務(wù)處理完畢,但是數(shù)據(jù)庫因?yàn)楣收隙鴽]有執(zhí)行事務(wù)的錯(cuò)誤。事務(wù)控制分類編

31、程式事務(wù)控制自己手動(dòng)控制事務(wù),就叫做編程式事務(wù)控制。Jdbc 代碼:mite(false); / 設(shè)置手動(dòng)控制事務(wù)Hibernate 代碼:Session.beginTransaction();/ 開啟一個(gè)事務(wù)【細(xì)粒度的事務(wù)控制: 可以對(duì)指定的方法、指定的方法的某幾行添加事務(wù)控制】(比較靈活,但開發(fā)起來比較繁瑣: 每次都要開啟、提交、回滾.)式事務(wù)控制Spring 提供了對(duì)事務(wù)的管理, 這個(gè)就明式事務(wù)管理。Spring 提供了對(duì)事務(wù)控制的實(shí)現(xiàn)。用戶如果想用 Spring 的式事務(wù)管理,只需要在配置文件中配置即可; 不想使用時(shí)直接移除配置。這個(gè)實(shí)現(xiàn)了對(duì)事務(wù)控制的最大程度的解耦。Spring式事務(wù)

32、管理,實(shí)現(xiàn)就是基于 Aop?!敬至6鹊氖聞?wù)控制: 只能給整個(gè)方法應(yīng)用事務(wù),不可以對(duì)方法的某幾行應(yīng)用事務(wù)?!?因?yàn)?aop的是方法。)Spring式事務(wù)管理器類:Jdbc 技術(shù):DataSourceTransactionManagerHibernate 技術(shù):HibernateTransactionManager手寫 Spring 事務(wù)框架編程事務(wù)實(shí)現(xiàn)概述所謂編程式事務(wù)指的是通過編碼方式實(shí)現(xiàn)事務(wù), 即類似于 JDBC 編程實(shí)現(xiàn)事務(wù)管理。管理使用TransactionTemplate 或者直接使用底層的 PlatformTransactionManager。對(duì)于編程式事務(wù)管理,spring推薦使用

33、 TransactionTemplate。案例使用編程事務(wù)實(shí)現(xiàn)手動(dòng)事務(wù)使用編程事務(wù)實(shí)現(xiàn),手動(dòng)事務(wù) begin、commit、rollbackComponentpublic class TransactionUtils Autowiredprivate DataSourceTransactionManager dataSourceTransactionManager;/ 開啟事務(wù)public TransactionStatus begin() TransactionStatus transaction = dataSourceTransactionManager.getTransaction(n

34、ew DefaultTransactionAttribute();return transaction;/ 提交事務(wù)public void commit(TransactionStatus transactionStatus) dataSourceTranmit(transactionStatus);/ 回滾事務(wù)public void rollback(TransactionStatus transactionStatus) dataSourceTransactionManager.rollback(transactionStatus);AOP 技術(shù)封裝手動(dòng)事務(wù)Component Aspect

35、public class AopTransaction Autowiredprivate TransactionUtils transactionUtils;/ / 異常通知AfterThrowing("execution(* com.itmayiedu.service.UserService.add(.)")public void afterThrowing() System.out.println("程序已經(jīng)回滾");Servicepublic class UserService Autowiredprivate UserDao userDao; A

36、utowiredprivate TransactionUtils transactionUtils;public void add() TransactionStatus transactionStatus = null; try transactionStatus = transactionUtils.begin(); userDao.add("wangmazi", 27);int i = 1 / 0; System.out.println("我是add方法"); userDao.add("zhangsan", 16);trmit(

37、transactionStatus); catch (Exception e) e.printStackTrace(); finally if (transactionStatus != null) transactionStatus.rollbackToSavepoint(transactionStatus);使用事務(wù)注意事項(xiàng)事務(wù)是程序運(yùn)行如果沒有錯(cuò)誤,會(huì)自動(dòng)提交事物,如果程序運(yùn)行發(fā)生異常,則會(huì)自動(dòng)回滾。如果使用了 try 捕獲異常時(shí).一定要在 catch 里面手動(dòng)回滾。事務(wù)手動(dòng)回滾代碼TransactionAspectSupport.currentTransactionStatus().s

38、etRollbackOnly();事務(wù)實(shí)現(xiàn)概述管理建立在 AOP 之上的。其本質(zhì)是對(duì)方法前后進(jìn)行,然后在目標(biāo)方法開始之前創(chuàng)建或者加入一個(gè)事務(wù),在執(zhí)行完目標(biāo)方法之后根據(jù)執(zhí)行情況提交或者回滾事務(wù)。式事務(wù)最大的優(yōu)點(diǎn)就是不需要通過編程的方式管理事務(wù),這樣就不需要在業(yè)務(wù)邏輯代碼中摻雜事務(wù)管理的代碼,只需在配置文件中做相關(guān)的事務(wù)規(guī)則(或通過基于Transactional 注解的方式),便可以將事務(wù)規(guī)則應(yīng)用到業(yè)務(wù)邏輯中。顯然式事務(wù)管理要優(yōu)于編程式事務(wù)管理,這正是 spring 倡導(dǎo)的非侵入式的開發(fā)方式。式事務(wù)管理使業(yè)務(wù)代碼不受污染,一個(gè)普通的 POJO 對(duì)象,只要加上注解就可以獲得完全的事務(wù)支持。和編程式事

39、務(wù)相比,式事務(wù)唯一不足地方是,后者的最細(xì)粒度只能作用到方法級(jí)別,無法做到像編程式事務(wù)那樣可以作用到代碼塊級(jí)別。但是即便有這樣的需求,也存在很多變通的方法,比如,可以將需要進(jìn)行事務(wù)管理的代碼塊為方法等等。/ 獲取程序當(dāng)前事務(wù) 進(jìn)行回滾TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();/ 環(huán)繞通知Around("execution(* com.itmayiedu.service.UserService.add(.)")public void around(ProceedingJoinPoi

40、nt proceedingJoinPoint) throws Throwable System.out.println("開啟事務(wù)");TransactionStatus begin = transactionUtils.begin();proceedingJoinPceed(); trmit(begin);System.out.println("提交事務(wù)");XML 實(shí)現(xiàn)注解版本<beans xmlns=""xmlns:xsi="" xmlns:p=""xmlns:con

41、text=""xmlns:aop="" xmlns:tx=""xsi:schemaLocation=""><!- 開啟注解 -><ponent-scan base-package="com.itmayiedu"><ponent-scan><!- 1. 數(shù)據(jù)源對(duì)象: C3P0連接池 -><bean id="dataSource" class="com.mboPooledDataSource">

42、<property name="driverClass" value="com.mysql.jdbc.Driver"></property><property name="jdbcUrl" value="jdbc:mysql:/localhost:3306/test"></property><property name="user" value="root"></property><property

43、 name="password" value="root"></property></bean><!- 2. JdbcTemplate工具類實(shí)例 -><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></propert

44、y></bean><!- 配置事物 -><bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!- 開啟注解事物 -><tx

45、:annotation-driven transaction-manager="dataSourceTransactionManager" /></beans>用法手寫 Spring 注解版本事務(wù)注解Jdk1.5 新增新技術(shù),注解。很多框架為了簡(jiǎn)化代碼,都會(huì)提供有些注解。可以理解為插件,是代碼級(jí)別的插件,在類的方法上寫:,就是在代碼上了一個(gè)插件。注解也不能影響代碼的實(shí)際邏輯,僅僅起到輔助性的作用。注解分類:內(nèi)置注解(也成為元注解 jdk 自帶注解)、自定義注解(Spring 框架)什么是內(nèi)置注解(1) SuppressWarnings 再程序前面加上可以在

46、 javac 編譯中去除警告-階段是 SOURCE(2) Deprecated 帶有標(biāo)記的包,方法,字段說明其過時(shí)階段是 SOURCE(3) Overricle 打上這個(gè)標(biāo)記說明該方法是將父類的方法重寫-階段是 SOURCEOverricle 案例演示Deprecated 案例演示SuppressWarnings 案例演示new Date().parse("");Overridepublic String toString() return null;Transactionalpublic void add() userDao.add("wangmazi"

47、;, 27);int i = 1 / 0; System.out.println("我是add方法"); userDao.add("zhangsan", 16);實(shí)現(xiàn)自定義注解元注解的作用就是負(fù)責(zé)注解其他注解。Java5.0 定義了 4 個(gè)標(biāo)準(zhǔn)的 meta-annotation 類型,它們被用來提供對(duì)其它 annotation 類型作說明。Java5.0 定義的元注解:TargetTarget 說明了 Annotation 所修飾的對(duì)象范圍:Annotation 可被用于 packages、types(類、接口、枚舉、Annotation 類型)、類型成

48、員(方法、構(gòu)造方法、成員變量、枚舉值)、方法參數(shù)和本地變量(如循環(huán)變量、catch 參數(shù))。在 Annotation 類型的中使用了 target 可更加明晰其修飾的目標(biāo)。.5.6.7.CONSTRUCTOR:用于描述構(gòu)造器FIELD:用于描述域 LOCAL_VARIABLE:用于描述局部變量METHOD:用于描述方法PACKAGE:用于描述包PARAMETER:用于描述參數(shù)TYPE:用于描述類、接口(包括注解類型) 或 enum2.Retention表示需要在什么級(jí)別保存該注釋信息,用于描述注解的生命周期(即:被描述的注解在什么范圍內(nèi)有效)3. Documented4. Inh

49、erited使用interface 定義注解。Target(value = ElementType.METHOD ) Retention(RetentionPolicy.RUNTIME) public interface AddAnnotation int userId() defaultt 0;String userName() default "默認(rèn)名稱"Stringarrays();反射注解信息public static void main(String args) throws ClassNotFoundException SuppressWarnings( &qu

50、ot;all" )public void save() java.util.List list = new ArrayList();自定義事務(wù)注解/編程事務(wù)(需要手動(dòng)begin 手動(dòng)回滾 手都提交)Component()Scope("prototype") / 設(shè)置成原型解決線程安全public class TransactionUtils private TransactionStatus transactionStatus;/ 獲取事務(wù)源Autowiredprivate DataSourceTransactionManager dataSourceTransa

51、ctionManager;/ 開啟事務(wù)public TransactionStatus begin() transactionStatus = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute();Class classInfo = Class.forName("com.itmayiedu.entity.User");/ 獲取到所有方法Method methods = classInfo.getDeclaredMethods();for (Method method : m

52、ethods) System.out.println(method);AddAnnotation declaredAnnotation = method.getDeclaredAnnotation(AddAnnotation.class);if (declaredAnnotation = null) / 結(jié)束本次循環(huán)continue;/ 獲取userIdint userId = declaredAnnotation.userId(); System.out.println("userId:" + userId);/ 獲取userNameString userName = d

53、eclaredAnnotation.userName(); System.out.println("userName:" + userName);/ 獲取arraysString arrays = declaredAnnotation.arrays();for (String str : arrays) System.out.println("str:" + str);return transactionStatus;/ 提交事務(wù)public void commit(TransactionStatus transaction) dataSourceTra

54、nmit(transaction);/ 回滾事務(wù)public void rollback() System.out.println("rollback");dataSourceTransactionManager.rollback(transactionStatus);注解類Autowiredprivate TransactionUtils transactionUtils;AfterThrowing("execution(* com.itmayiedu.service.*.*.*(.)")public void afterThrowing() thro

55、ws NoSuchMethodException, SecurityException / isRollback(proceedingJoinPoint); System.out.println("程序發(fā)生異常");/ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();/ TransactionStatus currentTransactionStatus =/ TransactionAspectSupport.currentTransactionStatus();/ System.o

56、ut.println("currentTransactionStatus:" +/ currentTransactionStatus); transactionUtils.rollback();/ / 環(huán)繞通知 在方法之前和之后處理事情Around("execution(* com.itmayiedu.service.*.*.*(.)")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable / 調(diào)用方法之前執(zhí)行TransactionStatus transactionStatus = begin(proceedingJoinPoint); proceedingJoinPceed();/調(diào)用方法: 如果調(diào)用方法拋出異常執(zhí)行后面代碼/ 調(diào)用方法之后執(zhí)行commit(transactionStatus);public TransactionStatus begin(ProceedingJo

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論