@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)類AnnotationAwareAspectJAutoProxyCreator
的postProcessAfterInstantiation
方法來實(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;
Class>targetClass=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
List
通過分析List
返回的是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.
Class>targetClass=(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,Class>targetClass,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
總結(jié)
最終可以總結(jié)一下整個流程,跟開始的猜想對照。
來源:blog.csdn.net/qq_20597727/article/details/84868035
-
代碼
+關(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)載請注明出處。
發(fā)布評論請先 登錄
如何將一個FA模型開發(fā)的聲明式范式應(yīng)用切換到Stage模型
聲明式資源管理方法
SSM與Hibernate的整合使用
SSM框架的性能優(yōu)化技巧 SSM框架中RESTful API的實(shí)現(xiàn)
SSM框架在Java開發(fā)中的應(yīng)用 如何使用SSM進(jìn)行web開發(fā)
Spring 應(yīng)用合并之路(二):峰回路轉(zhuǎn),柳暗花明
“宇宙猜想”聯(lián)合LEKEVR、有家嗨店共同打造商圈VR大空間放映廳

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

全新NVIDIA NIM微服務(wù)實(shí)現(xiàn)突破性進(jìn)展
如何在反激式拓?fù)?b class='flag-5'>中實(shí)現(xiàn)軟啟動

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

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

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

評論