在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

spring中聲明式事務(wù)實(shí)現(xiàn)原理猜想

Android編程精選 ? 來源:CSDN博客 ? 作者:一擼向北 ? 2021-10-13 09:20 ? 次閱讀

@Transactional注解簡介

@Transactional是spring中聲明式事務(wù)管理的注解配置方式,相信這個注解的作用大家都很清楚。@Transactional注解可以幫助我們把事務(wù)開啟、提交或者回滾的操作,通過aop的方式進(jìn)行管理。

通過@Transactional注解就能讓spring為我們管理事務(wù),免去了重復(fù)的事務(wù)管理邏輯,減少對業(yè)務(wù)代碼的侵入,使我們開發(fā)人員能夠?qū)W⒂跇I(yè)務(wù)層面開發(fā)。

我們知道實(shí)現(xiàn)@Transactional原理是基于spring aop,aop又是動態(tài)代理模式的實(shí)現(xiàn),通過對源碼的閱讀,總結(jié)出下面的步驟來了解實(shí)際中,在spring 是如何利用aop來實(shí)現(xiàn)@Transactional的功能的。

spring中聲明式事務(wù)實(shí)現(xiàn)原理猜想

首先,對于spring中aop實(shí)現(xiàn)原理有了解的話,應(yīng)該知道想要對一個方法進(jìn)行代理的話,肯定需要定義切點(diǎn)。在@Transactional的實(shí)現(xiàn)中,同樣如此,spring為我們定義了以 @Transactional 注解為植入點(diǎn)的切點(diǎn),這樣才能知道@Transactional注解標(biāo)注的方法需要被代理。

有了切面定義之后,在spring的bean的初始化過程中,就需要對實(shí)例化的bean進(jìn)行代理,并且生成代理對象。

生成代理對象的代理邏輯中,進(jìn)行方法調(diào)用時,需要先獲取切面邏輯,@Transactional注解的切面邏輯類似于@Around,在spring中是實(shí)現(xiàn)一種類似代理邏輯。

@Transactional作用

根據(jù)上面的原理猜想,下面簡單介紹每個步驟的源碼以進(jìn)行驗(yàn)證。

首先是@Transactional,作用是定義代理植入點(diǎn)。我們知道代理對象創(chuàng)建的通過BeanPostProcessor的實(shí)現(xiàn)類AnnotationAwareAspectJAutoProxyCreatorpostProcessAfterInstantiation方法來實(shí)現(xiàn)個,如果需要進(jìn)行代理,那么在這個方法就會返回一個代理對象給容器,同時判斷植入點(diǎn)也是在這個方法中。

那么下面開始分析,在配置好注解驅(qū)動方式的事務(wù)管理之后,spring會在ioc容器創(chuàng)建一個BeanFactoryTransactionAttributeSourceAdvisor實(shí)例,這個實(shí)例可以看作是一個切點(diǎn),在判斷一個bean在初始化過程中是否需要創(chuàng)建代理對象,都需要驗(yàn)證一次BeanFactoryTransactionAttributeSourceAdvisor是否是適用這個bean的切點(diǎn)。如果是,就需要創(chuàng)建代理對象,并且把BeanFactoryTransactionAttributeSourceAdvisor實(shí)例注入到代理對象中。

前文我們知道在AopUtils#findAdvisorsThatCanApply中判斷切面是否適用當(dāng)前bean,可以在這個地方斷點(diǎn)分析調(diào)用堆棧,AopUtils#findAdvisorsThatCanApply一致調(diào)用,最終通過以下代碼判斷是否適用切點(diǎn)。

  • AbstractFallbackTransactionAttributeSource#computeTransactionAttribute(Method method, Class targetClass)這里可以根據(jù)參數(shù)打上條件斷點(diǎn)進(jìn)行調(diào)試分析調(diào)用棧,targetClass就是目標(biāo)class …一系列調(diào)用
  • 最終SpringTransactionAnnotationParser#parseTransactionAnnotation(java.lang.reflect.AnnotatedElement)
@Override
publicTransactionAttributeparseTransactionAnnotation(AnnotatedElementae){
//這里就是分析Method是否被@Transactional注解標(biāo)注,有的話,不用說BeanFactoryTransactionAttributeSourceAdvisor適配當(dāng)前bean,進(jìn)行代理,并且注入切點(diǎn)
//BeanFactoryTransactionAttributeSourceAdvisor
AnnotationAttributesattributes=AnnotatedElementUtils.getMergedAnnotationAttributes(ae,Transactional.class);
if(attributes!=null){
returnparseTransactionAnnotation(attributes);
}
else{
returnnull;
}
}

上面就是判斷是否需要根據(jù)@Transactional進(jìn)行代理對象創(chuàng)建的判斷過程。@Transactional的作用一個就是標(biāo)識方法需要被代理,一個就是攜帶事務(wù)管理需要的一些屬性信息。

動態(tài)代理邏輯實(shí)現(xiàn)

【aop實(shí)現(xiàn)原理分析】中知道,aop最終的代理對象的代理方法是

  • DynamicAdvisedInterceptor#intercept

所以我們可以在這個方法斷點(diǎn)分析代理邏輯。往期的面試題,點(diǎn)擊查看

@Override
publicObjectintercept(Objectproxy,Methodmethod,Object[]args,MethodProxymethodProxy)throwsThrowable{
ObjectoldProxy=null;
booleansetProxyContext=false;
ClasstargetClass=null;
Objecttarget=null;
try{
if(this.advised.exposeProxy){
//Makeinvocationavailableifnecessary.
oldProxy=AopContext.setCurrentProxy(proxy);
setProxyContext=true;
}
//Maybenull.Getaslateaspossibletominimizethetimewe
//"own"thetarget,incaseitcomesfromapool...
target=getTarget();
if(target!=null){
targetClass=target.getClass();
}
//follow
Listchain=this.advised.getInterceptorsAndDynamicInterceptionAdvice(method,targetClass);
ObjectretVal;
//CheckwhetherweonlyhaveoneInvokerInterceptor:thatis,
//norealadvice,butjustreflectiveinvocationofthetarget.
if(chain.isEmpty()&&Modifier.isPublic(method.getModifiers())){
//WecanskipcreatingaMethodInvocation:justinvokethetargetdirectly.
//NotethatthefinalinvokermustbeanInvokerInterceptor,soweknow
//itdoesnothingbutareflectiveoperationonthetarget,andnohot
//swappingorfancyproxying.
Object[]argsToUse=AopProxyUtils.adaptArgumentsIfNecessary(method,args);
retVal=methodProxy.invoke(target,argsToUse);
}
else{
//Weneedtocreateamethodinvocation...
retVal=newCglibMethodInvocation(proxy,target,method,args,targetClass,chain,methodProxy).proceed();
}
retVal=processReturnType(proxy,target,method,retVal);
returnretVal;
}
finally{
if(target!=null){
releaseTarget(target);
}
if(setProxyContext){
//Restoreoldproxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}

		

通過分析List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass)返回的是TransactionInterceptor,利用TransactionInterceptor是如何實(shí)現(xiàn)代理邏輯調(diào)用的?

跟蹤new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();

發(fā)現(xiàn)最終是調(diào)用TransactionInterceptor#invoke方法,并且把CglibMethodInvocation注入到invoke方法中,從上面可以看到CglibMethodInvocation是包裝了目標(biāo)對象的方法調(diào)用的所有必須信息,因此,在TransactionInterceptor#invoke里面也是可以調(diào)用目標(biāo)方法的,并且還可以實(shí)現(xiàn)類似@Around的邏輯,在目標(biāo)方法調(diào)用前后繼續(xù)注入一些其他邏輯,比如事務(wù)管理邏輯。

TransactionInterceptor–最終事務(wù)管理者

下面看代碼。

  • TransactionInterceptor#invoke
@Override
publicObjectinvoke(finalMethodInvocationinvocation)throwsThrowable{
//Workoutthetargetclass:maybe{@codenull}.
//TheTransactionAttributeSourceshouldbepassedthetargetclass
//aswellasthemethod,whichmaybefromaninterface.
ClasstargetClass=(invocation.getThis()!=null?AopUtils.getTargetClass(invocation.getThis()):null);

//AdapttoTransactionAspectSupport'sinvokeWithinTransaction...
returninvokeWithinTransaction(invocation.getMethod(),targetClass,newInvocationCallback(){
@Override
publicObjectproceedWithInvocation()throwsThrowable{
returninvocation.proceed();
}
});
}

繼續(xù)跟蹤invokeWithinTransaction,下面的代碼中其實(shí)就可以看出一些邏輯端倪,就是我們猜想的實(shí)現(xiàn)方式,事務(wù)管理。

protectedObjectinvokeWithinTransaction(Methodmethod,ClasstargetClass,finalInvocationCallbackinvocation)
throwsThrowable{

//Ifthetransactionattributeisnull,themethodisnon-transactional.
finalTransactionAttributetxAttr=getTransactionAttributeSource().getTransactionAttribute(method,targetClass);
finalPlatformTransactionManagertm=determineTransactionManager(txAttr);
finalStringjoinpointIdentification=methodIdentification(method,targetClass);

if(txAttr==null||!(tminstanceofCallbackPreferringPlatformTransactionManager)){
//StandardtransactiondemarcationwithgetTransactionandcommit/rollbackcalls.
//開啟事務(wù)
TransactionInfotxInfo=createTransactionIfNecessary(tm,txAttr,joinpointIdentification);
ObjectretVal=null;
try{
//Thisisanaroundadvice:Invokethenextinterceptorinthechain.
//Thiswillnormallyresultinatargetobjectbeinginvoked.
//方法調(diào)用
retVal=invocation.proceedWithInvocation();
}
catch(Throwableex){
//targetinvocationexception
//回滾事務(wù)
completeTransactionAfterThrowing(txInfo,ex);
throwex;
}
finally{
cleanupTransactionInfo(txInfo);
}
//提交事務(wù)
commitTransactionAfterReturning(txInfo);
returnretVal;
}

else{
//It'saCallbackPreferringPlatformTransactionManager:passaTransactionCallbackin.
try{
Objectresult=((CallbackPreferringPlatformTransactionManager)tm).execute(txAttr,
newTransactionCallback(){
@Override
publicObjectdoInTransaction(TransactionStatusstatus){
TransactionInfotxInfo=prepareTransactionInfo(tm,txAttr,joinpointIdentification,status);
try{
returninvocation.proceedWithInvocation();
}
catch(Throwableex){
if(txAttr.rollbackOn(ex)){
//ARuntimeException:willleadtoarollback.
if(exinstanceofRuntimeException){
throw(RuntimeException)ex;
}
else{
thrownewThrowableHolderException(ex);
}
}
else{
//Anormalreturnvalue:willleadtoacommit.
returnnewThrowableHolder(ex);
}
}
finally{
cleanupTransactionInfo(txInfo);
}
}
});

//Checkresult:ItmightindicateaThrowabletorethrow.
if(resultinstanceofThrowableHolder){
throw((ThrowableHolder)result).getThrowable();
}
else{
returnresult;
}
}
catch(ThrowableHolderExceptionex){
throwex.getCause();
}
}
}

		

總結(jié)

最終可以總結(jié)一下整個流程,跟開始的猜想對照。

來源:blog.csdn.net/qq_20597727/article/details/84868035

責(zé)任編輯:haq
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4891

    瀏覽量

    70335
  • spring
    +關(guān)注

    關(guān)注

    0

    文章

    340

    瀏覽量

    14924

原文標(biāo)題:Spring的@Transactional如何實(shí)現(xiàn)的(必考)

文章出處:【微信號:AndroidPush,微信公眾號:Android編程精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    如何將一個FA模型開發(fā)的聲明范式應(yīng)用切換到Stage模型

    模型切換概述 本文介紹如何將一個FA模型開發(fā)的聲明范式應(yīng)用切換到Stage模型,您需要完成如下動作: 工程切換:新建一個Stage模型的應(yīng)用工程。 配置文件切換:config.json切換
    發(fā)表于 06-04 06:22

    白皮書:在HMI應(yīng)用實(shí)現(xiàn)高精度電容觸摸傳感器

    在HMI 應(yīng)用實(shí)現(xiàn)高精度電容觸摸傳感器
    的頭像 發(fā)表于 03-17 16:46 ?1208次閱讀
    白皮書:在HMI應(yīng)用<b class='flag-5'>中</b><b class='flag-5'>實(shí)現(xiàn)</b>高精度電容<b class='flag-5'>式</b>觸摸傳感器

    聲明資源管理方法

    1、管理k8s核心資源的三種基礎(chǔ)方法 陳述管理方法:主要依賴命令行CLI工具進(jìn)行管理 聲明管理方法:主要依賴統(tǒng)一資源配置清單(manifest)進(jìn)行管理 GUI管理方法:主要依賴
    的頭像 發(fā)表于 12-31 10:16 ?500次閱讀

    SSM與Hibernate的整合使用

    作為Java持久化框架的代表,常被整合到SSM框架。 SSM框架簡介 SSM框架是指Spring、SpringMVC和MyBatis三個框架的整合使用。Spring負(fù)責(zé)依賴注入和事務(wù)
    的頭像 發(fā)表于 12-17 09:14 ?529次閱讀

    SSM框架的性能優(yōu)化技巧 SSM框架RESTful API的實(shí)現(xiàn)

    : 緩存可以顯著提高系統(tǒng)的響應(yīng)速度。 在SSM,可以使用Redis或Memcached等緩存技術(shù)來緩存頻繁訪問的數(shù)據(jù),如數(shù)據(jù)庫查詢結(jié)果、用戶信息等。 同時,也可以利用Spring Cache抽象層來簡化
    的頭像 發(fā)表于 12-17 09:10 ?727次閱讀

    SSM框架在Java開發(fā)的應(yīng)用 如何使用SSM進(jìn)行web開發(fā)

    SSM框架,即Spring、SpringMVC和MyBatis的整合,是Java Web開發(fā)中常用的技術(shù)棧。它通過分層架構(gòu),實(shí)現(xiàn)了視圖、控制、業(yè)務(wù)邏輯和數(shù)據(jù)訪問的分離,提高了代碼的可維護(hù)性和可擴(kuò)展性
    的頭像 發(fā)表于 12-16 17:28 ?1492次閱讀

    Spring 應(yīng)用合并之路(二):峰回路轉(zhuǎn),柳暗花明

    提醒下,決定拋開 Spring Boot 內(nèi)置的父子容器方案,完全自己實(shí)現(xiàn)父子容器。 如何加載 web 項(xiàng)目? 現(xiàn)在的難題只有一個:如何加載 web 項(xiàng)目?加載完成后,如何持續(xù)持有 web 項(xiàng)目?經(jīng)過思考后,可以創(chuàng)建一個 boot 項(xiàng)目的
    的頭像 發(fā)表于 12-12 11:22 ?1098次閱讀

    “宇宙猜想”聯(lián)合LEKEVR、有家嗨店共同打造商圈VR大空間放映廳

    空間計(jì)算內(nèi)容服務(wù)商“宇宙猜想”與國內(nèi)VR體驗(yàn)館頭部品牌LEKEVR、有家嗨店達(dá)成戰(zhàn)略合作,共同打造全國商圈VR大空間放映廳。此次合作標(biāo)志著VR大空間產(chǎn)品進(jìn)一步普及化,同時也標(biāo)志著“宇宙猜想”在商業(yè)體
    的頭像 發(fā)表于 12-05 16:31 ?524次閱讀
    “宇宙<b class='flag-5'>猜想</b>”聯(lián)合LEKEVR、有家嗨店共同打造商圈VR大空間放映廳

    新展來襲!《宇宙猜想·啟程》宇宙主題VR沉浸體驗(yàn)展在天津博物館震撼啟幕

    11月30日,備受矚目的《宇宙猜想·啟程》——宇宙主題VR沉浸體驗(yàn)展正式落地天津博物館,為觀眾帶來了一場前所未有的宇宙探索之旅。此次展覽巧妙融合了XR、空間定位等前沿技術(shù),不僅展示了宇宙猜想
    的頭像 發(fā)表于 12-02 15:40 ?660次閱讀
    新展來襲!《宇宙<b class='flag-5'>猜想</b>·啟程》宇宙主題VR沉浸<b class='flag-5'>式</b>體驗(yàn)展在天津博物館震撼啟幕

    全新NVIDIA NIM微服務(wù)實(shí)現(xiàn)突破性進(jìn)展

    全新 NVIDIA NIM 微服務(wù)實(shí)現(xiàn)突破性進(jìn)展,可助力氣象技術(shù)公司開發(fā)和部署 AI 模型,實(shí)現(xiàn)對降雪、結(jié)冰和冰雹的預(yù)測。
    的頭像 發(fā)表于 11-21 10:07 ?620次閱讀

    Spring事務(wù)實(shí)現(xiàn)原理

    這些操作。 spring事務(wù)有編程式事務(wù)聲明事務(wù)兩種實(shí)現(xiàn)
    的頭像 發(fā)表于 11-08 10:10 ?1127次閱讀
    <b class='flag-5'>Spring</b><b class='flag-5'>事務(wù)實(shí)現(xiàn)</b>原理

    如何在反激拓?fù)?b class='flag-5'>中實(shí)現(xiàn)軟啟動

    電子發(fā)燒友網(wǎng)站提供《如何在反激拓?fù)?b class='flag-5'>中實(shí)現(xiàn)軟啟動.pdf》資料免費(fèi)下載
    發(fā)表于 09-04 11:09 ?0次下載
    如何在反激<b class='flag-5'>式</b>拓?fù)?b class='flag-5'>中</b><b class='flag-5'>實(shí)現(xiàn)</b>軟啟動

    Spring Cloud Gateway網(wǎng)關(guān)框架

    Spring Cloud Gateway網(wǎng)關(guān)框架 本軟件微服務(wù)架構(gòu)采用Spring Cloud Gateway網(wǎng)關(guān)控制框架,Spring Cloud Gateway是
    的頭像 發(fā)表于 08-22 09:58 ?695次閱讀
    <b class='flag-5'>Spring</b> Cloud Gateway網(wǎng)關(guān)框架

    鴻蒙開發(fā)Ability Kit程序框架服務(wù):聲明權(quán)限

    應(yīng)用在申請權(quán)限時,需要在項(xiàng)目的配置文件,逐個聲明需要的權(quán)限,否則應(yīng)用將無法獲取授權(quán)。
    的頭像 發(fā)表于 07-01 09:22 ?606次閱讀
    鴻蒙開發(fā)Ability Kit程序框架服務(wù):<b class='flag-5'>聲明</b>權(quán)限

    玩轉(zhuǎn)Spring狀態(tài)機(jī)

    說起Spring狀態(tài)機(jī),大家很容易聯(lián)想到這個狀態(tài)機(jī)和設(shè)計(jì)模式狀態(tài)模式的區(qū)別是啥呢?沒錯,Spring狀態(tài)機(jī)就是狀態(tài)模式的一種實(shí)現(xiàn),在介紹Sprin
    的頭像 發(fā)表于 06-25 14:21 ?1281次閱讀
    玩轉(zhuǎn)<b class='flag-5'>Spring</b>狀態(tài)機(jī)
    主站蜘蛛池模板: 国产免费一区二区三区香蕉精 | 天天看天天干天天操 | 国产精品特黄毛片 | 中文天堂网在线www 中文天堂资源在线www | 色婷婷精品 | 最近国语视频免费观看在线播放 | 亚洲色图欧美激情 | 么公的好大好硬好深好爽视频 | 丁香五月缴情在线 | 国产精品天天看大片特色视频 | 久久久综合色 | 一级特黄性色生活片一区二区 | 天天干天天草天天射 | 黄色美女免费网站 | 日韩日韩| 午夜剧场毛片 | 成人福利在线视频 | 欧美人与动另类在线 | 亚洲韩国欧美一区二区三区 | 天天色综合2 | 国产成人高清一区二区私人 | 天天操天天搞 | 亚洲国产成人在线 | 中文字幕网资源站永久资源 | 日本三级网址 | 免费色视频在线观看 | 午夜伦理片在线观看 | 午夜黄色福利 | 97午夜影院| 91在线操| 欧美一级视频在线 | 影院成人区精品一区二区婷婷丽春院影视 | 97综合视频 | 超大乳抖乳露双乳视频 | 天天干在线播放 | 日本视频免费高清一本18 | 天天做天天爱天天做天天吃中 | 4438x成人全国最大 | 韩国视频在线播放 | 欧美极品 | 女张腿男人桶羞羞漫画 |