最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

【面試】Spring事務面試考點吐血整理(建議珍藏)

 更新時間:2019年04月16日 11:34:58   作者:李新杰  
本文是小編給大家收藏整理的Spring事務面試考點,非常不錯,值得收藏,感興趣的朋友參考下吧

Starting from a joke

問:把大象放冰箱里,分幾步?

答:三步啊,第一、把冰箱門打開,第二、把大象放進去,第三、把冰箱門帶上。

問:實現(xiàn)Spring事務,分幾步?

答:三步啊,第一、找出需要事務的方法,第二、把事務加進去,第三、執(zhí)行事務。

You may find it's not a joke, it's serious。

Try to find an entrance

當你面對一個完全不熟悉的事物時,一定要想辦法找到一個突破口,然后逐步深入。那Spring事物的突破口在哪里呢?很明顯在@EnableTransactionManagement注解里,因為是它啟用了事物功能。

請看下圖:

發(fā)現(xiàn)注解還引入了一個類TransactionManagementConfigurationSelector。

再來看這個類,如下圖:

發(fā)現(xiàn)如果采用代理的方式時,又引入了一個類ProxyTransactionManagementConfiguration。

接著看這個類(重點來了),如下圖:

發(fā)現(xiàn)這個類往容器中注冊了3個bean,第一個是BeanFactoryTransactionAttributeSourceAdvisor。它以Advisor結(jié)尾說明它是Spring AOP范疇里的東西。

在AOP里,Advisor = Pointcut + Advice,Pointcut是切入點,表示要攔截的方法,Advice是增強,表示要加進去的事物功能。

再看看另外兩個注冊的bean,就是和這兩個相關(guān)的。其中TransactionInterceptor就是一個Advice,因為它實現(xiàn)了Advice接口,包含了把事物加進去的邏輯。

TransactionAttributeSource雖然不是一個Pointcut,但是它被Pointcut所用,用于檢測一個類的方法上是否有@Transactional注解,來確定該方法是否需要事物增強。

從下圖中也可以看出這一點:

可以看到這個bean通過下面的set方法被設置進去,然后又用在了Pointcut的類里了。

整體來看,此部分的結(jié)構(gòu)和功能劃分還是非常清晰的。下面來逐一研究。

AOP切點

TransactionAttributeSourcePointcut類以Pointcut結(jié)尾,說明它是一個切入點,就是標識要被攔截的方法。類名的前綴部分表明了這個切入點的實現(xiàn)原理。

看下這個前綴是TransactionAttributeSource,它以Source結(jié)尾,說明它是一個源(即源泉,有向外提供東西的意思)。它的前綴是TransactionAttribute,即事務屬性。

由此可見,這個源可以向外提供事務屬性,其實就是判斷一個類的方法上是否標有@Transactional注解,如果有的話還可以獲取這個注解的屬性(即事務屬性)。

整體來說就是,Pointcut攔截住了方法,然后使用這個“源”去方法和類上獲取事務屬性,如果能獲取到,說明此方法需要參與事務,則進行事務增強,反之則不增強。

下面這張圖可以證明我們的想法:

可以看出matches方法的兩個參數(shù)就是一個方法(Method)和一個類(Class<?>)。最后從方法和類上獲取事務屬性,再進行是否為null判斷。

現(xiàn)在這個“源”還是個黑盒子,下面來揭開它的面紗。它的實現(xiàn)類是AnnotationTransactionAttributeSource,以Annotation開頭,說明是基于注解實現(xiàn)的。

下面圖是它的源碼的一部分:

第一個方法從類上找事務屬性,第二個方法從方法上找事務屬性,它倆都調(diào)用了第三個方法來實現(xiàn)。

PS:我們都知道,方法上的注解優(yōu)先級高于類上的,是因為找注解時先找方法上的,找不到時再去類上找。所以方法上的優(yōu)先級高。此部分代碼邏輯在父類里寫著呢,這里不再展示了。

第三個方法使用多個事務注解解析器(TransactionAnnotationParser)去解析注解,為啥是多個解析器呢?因為事務注解不僅Spring提供了,Java后來也提供了,就是javax.transaction.Transactional。

Spring對自己注解的解析器實現(xiàn)類是SpringTransactionAnnotationParser,如下圖:

可以看出使用工具類來讀取注解@Transactional的屬性,然后逐個解析出屬性值并進行類型轉(zhuǎn)換,接著把這些屬性封裝到一個類里,這個類其實就是事務屬性,即TransactionAttribute。

這個事務屬性繼承了事務定義接口,事務定義接口我們應該都很熟悉,如下圖:

這也證明了以前文章里說過的話,@Transactional注解的作用有兩個,一是表明要參與事務,二是表明如何參與事務,這些注解屬性就是來規(guī)定如何參與的。

這個事務屬性TransactionAttribute是個接口,它的實現(xiàn)類在這里就不再詳說了。

AOP增強

Advice就是AOP中的增強,TransactionInterceptor實現(xiàn)了Advice接口,所以它就是事務增強。

先來看下該接口,如下圖:

發(fā)現(xiàn)它只是一個空的標記接口。而且它的包名是org.aopalliance,是一個AOP聯(lián)盟組織,它制定的AOP規(guī)范。

先來了解下AOP領(lǐng)域的一些相關(guān)內(nèi)容,Pointcut是切入點,表示要攔截的方法。它是一個靜態(tài)的概念,即程序不運行時它也是存在的。

那么在真正運行時,已經(jīng)攔截住了,此時該怎么表示這個情況呢?是用Joinpoint來表示的,所以Joinpoint是一個運行時的概念,只有在運行時才存在。

請看Joinpoint接口,如下圖:

第一個方法proceed()是“繼續(xù)”的意思,調(diào)用它表示去執(zhí)行被攔截住的方法本身,返回方法本身的返回值。

第二個方法getThis()是獲取this對象,即方法運行時所在的目標對象。如果是靜態(tài)方法,則為null,因為靜態(tài)方法是屬于類本身的,運行時不需要對象。

第三個方法getStaticPart(),其實就表示了被攔截住的方法,即就是一個Method。Method其實算是“元數(shù)據(jù)”,是屬于類型本身的,也有“靜態(tài)”的意思。

再看一個接口,Invocation,它繼承了Joinpoint,如下圖:

方法getArguments()就表示運行時傳遞給被攔截住方法的參數(shù)。

再看一個接口,MethodInvocation,它繼承了Invocation,如下圖:

方法getMethod()返回一個Method,它就是當前正在執(zhí)行的方法,是對本攔截方法的一個友好實現(xiàn),返回相同的結(jié)果。

可見MethodInvocation接口已經(jīng)包含了一個方法調(diào)用的全量信息,方法,參數(shù),目標對象。這其實就是運行時被攔截住的東西。

再看下面這個接口,MethodInterceptor,方法攔截器,如下圖:

它只有一個方法invoke,方法參數(shù)就是上面介紹的MethodInvocation。所以攔截器可以使用這個參數(shù)來對目標方法進行調(diào)用,當然在調(diào)用前/后可以加入自己的邏輯。

TransactionInterceptor類就實現(xiàn)了這個接口,因此可以在對目標方法的調(diào)用前后插入事務邏輯代碼來進行事務增強。

下面是事務攔截器對該方法的實現(xiàn),如下圖:

它調(diào)用的invokeWithinTransaction方法是在父類里的,看下圖:

這個圖里做的事情較多,逐個來看:

前兩行獲取事務屬性“源”,再用這個“源”來獲取事務屬性。咦,有點奇怪,上面不是已經(jīng)獲取過了嗎?是的,上面是在Pointcut里獲取的,那只是用于判斷那個方法是否要被攔截而已。這里獲取的屬性才是真正用于事務的。

第三行是根據(jù)事務屬性,來確定出一個事務管理器來。

接下來是使用事務管理器打開事務。

接下來是對被攔截住的目標方法的調(diào)用執(zhí)行,當然要try/catch住這個執(zhí)行。

如果拋出了異常,則進行和異常相關(guān)的事務處理,然后將這個異常繼續(xù)向上拋出。

如果沒有拋出異常,則進行事務提交。

最后的else分支是對編程式事務的調(diào)用,事務的打開/提交/回滾是開發(fā)人員自己寫代碼控制,所以就不需要事務管理器操心了。

下面請看和異常相關(guān)的事務處理,如下圖:

判斷異常類型是否需要回滾,需要的話就回滾事務,不需要的話就繼續(xù)提交事務。

這里的整體結(jié)構(gòu)和邏輯流程也是比較清晰的,那是因為一方面得益于AOP領(lǐng)域的概念,另一方面是事務管理器屏蔽了事務的所有復雜性。

PS:事務管理器的內(nèi)容其實還是挺復雜的,下篇文章再詳細解說。

好了,以上是小編給大家介紹的Spring事務面試整理,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!

相關(guān)文章

  • SpringBoot中使用@Scheduled注解創(chuàng)建定時任務的實現(xiàn)

    SpringBoot中使用@Scheduled注解創(chuàng)建定時任務的實現(xiàn)

    這篇文章主要介紹了SpringBoot中使用@Scheduled注解創(chuàng)建定時任務的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • 44條Java代碼優(yōu)化建議

    44條Java代碼優(yōu)化建議

    代碼優(yōu)化的最重要的作用應該是:避免未知的錯誤。因此,在寫代碼的時候,從源頭開始注意各種細節(jié),權(quán)衡并使用最優(yōu)的選擇,將會很大程度上避免出現(xiàn)未知的錯誤,從長遠看也極大的降低了工作量
    2018-03-03
  • Mybatis中的延遲加載詳細解析

    Mybatis中的延遲加載詳細解析

    這篇文章主要介紹了Mybatis中的延遲加載詳細解析,延遲加載就是在真正需要使用數(shù)據(jù)時才發(fā)起查詢,不用的時候不進行查詢,按需加載(懶加載),需要的朋友可以參考下
    2023-12-12
  • 詳解SpringBoot中關(guān)于%2e的Trick

    詳解SpringBoot中關(guān)于%2e的Trick

    這篇文章主要介紹了SpringBoot中關(guān)于%2e的Trick,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • JVM實戰(zhàn)系列之CPU100%和內(nèi)存100%排查

    JVM實戰(zhàn)系列之CPU100%和內(nèi)存100%排查

    本文主要介紹了JVM實戰(zhàn)系列之CPU100%和內(nèi)存100%排查,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06
  • Java21增強對Emoji表情符號處理示例詳解

    Java21增強對Emoji表情符號處理示例詳解

    這篇文章主要為大家介紹了Java21增強對Emoji表情符號處理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • SpringBoot整合Mybatis-Plus實現(xiàn)微信注冊登錄的示例代碼

    SpringBoot整合Mybatis-Plus實現(xiàn)微信注冊登錄的示例代碼

    微信是不可或缺的通訊工具,本文主要介紹了SpringBoot整合Mybatis-Plus實現(xiàn)微信注冊登錄的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的可以了解一下
    2024-02-02
  • Spring Security 自定義短信登錄認證的實現(xiàn)

    Spring Security 自定義短信登錄認證的實現(xiàn)

    這篇文章主要介紹了Spring Security 自定義短信登錄認證的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • Spring mvc攔截器實現(xiàn)原理解析

    Spring mvc攔截器實現(xiàn)原理解析

    這篇文章主要介紹了Spring mvc攔截器實現(xiàn)原理解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • 詳解Java修飾符

    詳解Java修飾符

    Java語言提供了很多修飾符,主要分為以下兩類:訪問修飾符;非訪問修飾符。修飾符用來定義類、方法或者變量,通常放在語句的最前端。我們通過下面的例子來說明,下面就跟小編一起來看下吧
    2016-12-12

最新評論

芜湖县| 厦门市| 乌苏市| 武功县| 元阳县| 昌黎县| 右玉县| 兴安县| 徐水县| 永善县| 吕梁市| 嘉荫县| 夏邑县| 长汀县| 滁州市| 洪江市| 汨罗市| 江陵县| 上杭县| 敦煌市| 九龙县| 巴林右旗| 辽源市| 东城区| 旬阳县| 凤翔县| 长沙市| 绥芬河市| 邳州市| 高碑店市| 司法| 榆林市| 渑池县| 杭州市| 临邑县| 镇赉县| 邻水| 永嘉县| 宜君县| 福建省| 普洱|