主頁 >  其他 > Spring IOC、AOP與事務

Spring IOC、AOP與事務

2020-09-10 19:49:34 其他

是什么、為什么、怎么樣這大概是所有問題必經之路,也是我們解決問題的思路,

  • 什么是 IoC?
  • IoC 解決了什么問題?
  • IoC 和 DI 的區別?
  • 什么是 AOP?
  • AOP 解決了什么問題?
  • AOP 為什么叫做切面編程?在這里插入圖片描述

什么是IOC?
IoC (Inversion of control )控制反轉/反轉控制,它是一種思想不是一個技術實作,描述的是:Java 開發領域物件的創建以及管理的問題,
ioc的思想最核心的地方在于,資源不由使用資源的雙方管理,而由不使用資源的第三方管理,Spring IOC則是第三方,用于物件的創建以及管理,

要了解控制反轉IOC我覺得有必要先了解軟體設計的一個重要思想:依賴倒置原則——把原本的高層建筑依賴底層建筑“倒置”過來,變成底層建筑依賴高層建筑,高層建筑決定需要什么,底層去實作這樣的需求,但是高層并不用管底層是怎么實作的,這樣就不會出現前面的“牽一發動全身”的情況
在這里插入圖片描述

IoC 最常見以及最合理的實作方式叫做依賴注入(Dependency Injection,簡稱 DI),

控制反轉是目的,依賴注入是實作控制反轉的手段,

何為依賴,依賴什么?

程式運行需要依賴外部的資源,提供程式內物件的所需要的資料、資源,應用程式依賴于IoC容器,

何為注入,注入什么?

組態檔把資源從外部注入到內部,容器加載了外部的檔案、物件、資料,然后把這些資源注入給程式內的物件,維護了程式內外物件之間的依賴關系,

所以說,控制反轉是通過依賴注入實作的,像是「從不同角度描述的同一件事」:

  • IoC 是設計思想,DI 是具體的實作方式;
  • IoC 是理論,DI 是實踐;

從而實作物件之間的解藕,

當然,IoC 也可以通過其他的方式來實作,而 DI 只是 Spring 的選擇,
在這里插入圖片描述
為什么叫控制反轉
控制 :指的是物件創建(實體化、管理)的權力
反轉 :控制權交給外部環境(Spring 框架、IoC 容器)
誰控制誰,控制什么:傳統Java SE程式設計,我們直接在物件內部通過new進行創建物件,是程式主動去創建依賴物件;而IoC是有專門一個容器來創建這些物件,即由Ioc容器來控制物件的創建;誰控制誰?當然是IoC 容器控制了物件;控制什么?那就是主要控制了外部資源獲取(不只是物件包括比如檔案等),

●為何是反轉,哪些方面反轉了:有反轉就有正轉,傳統應用程式是由我們自己在物件中主動控制去直接獲取依賴物件,也就是正轉;而反轉則是由容器來幫忙創建及注入依賴物件;為何是反轉?因為由容器幫我們查找及注入依賴物件,物件只是被動的接受依賴物件,所以是反轉;哪些方面反轉了?依賴物件的獲取被反轉了,

IoC 解決了什么問題?
IoC 的思想就是兩方之間不互相依賴,由第三方容器來管理相關資源,這樣有什么好處呢?

解耦:物件之間的耦合度或者說依賴程度降低;
管理:資源變的容易管理;比如你用 Spring 容器提供的話很容易就可以實作一個單例,

將物件之間的相互依賴關系交給 IoC 容器來管理,并由 IoC 容器完成物件的注入,這樣可以很大程度上簡化應用的開發,把應用從復雜的依賴關系中解放出來, IoC 容器就像是一個工廠一樣,當我們需要創建一個物件的時候,只需要配置好組態檔/注解即可,完全不用考慮物件是如何被創建出來的,
推薦閱讀:https://www.zhihu.com/question/23277575/answer/169698662

Spring的IOC理解
(1)IOC就是控制反轉,是指創建物件的控制權的轉移,以前創建物件的主動權和時機是由自己把控
的,而現在這種權力轉移到Spring容器中,并由容器根據組態檔去創建實體和管理各個實體之間的依
賴關系,物件與物件之間松散耦合,也利于功能的復用,DI依賴注入,和控制反轉是同一個概念的不同
角度的描述,即 應用程式在運行時依賴IoC容器來動態注入物件需要的外部資源,
(2)最直觀的表達就是,IOC讓物件的創建不用去new了,可以由spring自動生產,使用java的反射機
制,根據組態檔在運行時動態的去創建物件以及管理物件,并呼叫物件的方法的,
(3)Spring的IOC有三種注入方式 :構造器注入、setter方法注入、根據注解注入,

IoC讓相互協作的組件保持松散的耦合,而AOP編程允許你把遍布于應用各層的功能分離出來形成可重用的功能組件,

Spring IOC實作流程原理

在Spring中,最基本的IOC容器介面是BeanFactory - 這個介面為具體的IOC容器的實作作了最基本的功能規定,IOC 總體來說有兩處地方最重要,一個是創建 Bean 容器,一個是初始化 Bean.
啟動 Spring 容器

public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(“classpath:applicationfile.xml”);
}

ApplicationContext 啟動程序中,會負責創建實體 Bean,往各個 Bean 中注入依賴等.
在這里插入圖片描述spring ioc初始化流程?
resource定位 即尋找?戶定義的bean資源,由 ResourceLoader通過統?的接?Resource接?來完成beanDefinition載? BeanDefinitionReader讀取、決議Resource定位的資源 成BeanDefinition 載?到ioc中(通過HashMap進?維護BD) BeanDefinition注冊 即向IOC容器注冊這些BeanDefinition, 通過BeanDefinitionRegistery實作

BeanFactory,從名字上也很好理解,生產 bean 的工廠,它負責生產和管理各個 bean 實體,
流程:
啟動容器->創建bean工廠(BeanFactory)->依靠BeanFactory來getBean->創建bean->創建bean實體->通過反射生成bean->填充屬性,注入依賴->初始化bean

核心方法

@Override
public void refresh() throws BeansException, IllegalStateException {
   // 來個鎖,不然 refresh() 還沒結束,你又來個啟動或銷毀容器的操作,那不就亂套了嘛
   synchronized (this.startupShutdownMonitor) {

      // 準備作業,記錄下容器的啟動時間、標記“已啟動”狀態、處理組態檔中的占位符
      prepareRefresh();

      // 這步比較關鍵,這步完成后,組態檔就會決議成一個個 Bean 定義,注冊到 BeanFactory 中,
      // 當然,這里說的 Bean 還沒有初始化,只是配置資訊都提取出來了,
      // 注冊也只是將這些資訊都保存到了注冊中心(說到底核心是一個 beanName-> beanDefinition 的 map)
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // 設定 BeanFactory 的類加載器,添加幾個 BeanPostProcessor,手動注冊幾個特殊的 bean
      // 準備 Bean 容器: prepareBeanFactory,Spring 把我們在 xml 配置的 bean 都注冊以后,會"手動"注冊一些特殊的 bean,
      prepareBeanFactory(beanFactory);

      try {
         // 【這里需要知道 BeanFactoryPostProcessor 這個知識點,Bean 如果實作了此介面,
         // 那么在容器初始化以后,Spring 會負責呼叫里面的 postProcessBeanFactory 方法,】

         // 這里是提供給子類的擴展點,到這里的時候,所有的 Bean 都加載、注冊完成了,但是都還沒有初始化
         // 具體的子類可以在這步的時候添加一些特殊的 BeanFactoryPostProcessor 的實作類或做點什么事
         postProcessBeanFactory(beanFactory);
         // 呼叫 BeanFactoryPostProcessor 各個實作類的 postProcessBeanFactory(factory) 方法
         invokeBeanFactoryPostProcessors(beanFactory);

         // 注冊 BeanPostProcessor 的實作類,注意看和 BeanFactoryPostProcessor 的區別
         // 此介面兩個方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
         // 兩個方法分別在 Bean 初始化之前和初始化之后得到執行,注意,到這里 Bean 還沒初始化
         registerBeanPostProcessors(beanFactory);

         // 初始化當前 ApplicationContext 的 MessageSource,國際化
         initMessageSource();

         // 初始化當前 ApplicationContext 的事件廣播器
         initApplicationEventMulticaster();

         // 從方法名就可以知道,典型的模板方法(鉤子方法),
         // 具體的子類可以在這里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
         onRefresh();

         // 注冊事件監聽器,監聽器需要實作 ApplicationListener 介面,
         registerListeners();

         // 重點,重點,重點
         // 初始化所有的 singleton beans
         //(lazy-init 的除外)
         finishBeanFactoryInitialization(beanFactory);

         // 最后,廣播事件,ApplicationContext 初始化完成
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         // 銷毀已經初始化的 singleton 的 Beans,以免有些 bean 會一直占用資源
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // 把例外往外拋
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}

在這里插入圖片描述

在這里插入圖片描述在這里插入圖片描述spring的類加載
在這里插入圖片描述類從被加載到虛擬機記憶體中開始,直到卸載出記憶體為止,它的整個生命周期包括了:加載、驗證、準備、決議、初始化、使用和卸載這7個階段,其中,驗證、準備和決議這三個部分統稱為連接(linking),
當然Spring中的加載程序中,其加載程序還是遵循JVM的加載程序,
JVM的類加載
在這里插入圖片描述

DI依賴注?流程? (實體化,處理Bean之間的依賴關系)
程序在Ioc初始化后,依賴注?的程序是?戶第?次向IoC容器索要Bean時觸發

  • 如果設定lazy-init=true,會在第?次getBean的時候才初始化bean, lazy-init=false,會容器啟動的時候直接初始化(singleton bean);
  • 調?BeanFactory.getBean()?成bean的;
  • ?成bean程序運?裝飾器模式產?的bean都是beanWrapper(bean的增強);

依賴注?怎么處理bean之間的依賴關系?
其實就是通過在beanDefinition載?時,如果bean有依賴關系,通過占位符來代替,在調?getbean時候,如果遇到占位符,從ioc?獲取bean注?到本實體來
Spring的IOC注??式
一、構造器注入
將被依賴物件通過建構式的引數注入給依賴物件,并且在初始化物件的時候注入,
優點:
物件初始化完成后便可獲得可使用的物件,
缺點:
當需要注入的物件很多時,構造器引數串列將會很長;
不夠靈活,若有多種注入方式,每種方式只需注入指定幾個依賴,那么就需要提供多個多載的建構式,麻煩,
二、setter方法注入
IoC Service Provider通過呼叫成員變數提供的setter函式將被依賴物件注入給依賴類,
優點:
靈活,可以選擇性地注入需要的物件,
缺點:
依賴物件初始化完成后由于尚未注入被依賴物件,因此還不能使用,
三、介面注入
依賴類必須要實作指定的介面,然后實作該介面中的一個函式,該函式就是用于依賴注入,該函式的引數就是要注入的物件,
優點
介面注入中,介面的名字、函式的名字都不重要,只要保證函式的引數是要注入的物件型別即可,
缺點:
侵入性太強,不建議使用,
PS:什么是侵入性?
如果類A要使用別人提供的一個功能,若為了使用這功能,需要在自己的類中增加額外的代碼,這就是侵入性

Bean的?命周期?

  • 實體化Bean: Ioc容器通過獲取BeanDefinition物件中的資訊進?實體化,實體化物件被包裝在BeanWrapper物件中
  • 設定物件屬性(DI):通過BeanWrapper提供的設定屬性的接?完成屬性依賴注?;
  • 注?Aware接?(BeanFactoryAware, 可以?這個?式來獲取其它 Bean,ApplicationContextAware):Spring會檢測該物件是否實作了xxxAware接?,并將相關的xxxAware實體注?給bean
  • BeanPostProcessor:?定義的處理(分前置處理和后置處理)
  • InitializingBean和init-method:執?我們??定義的初始化?法
  • 使?
  • destroy:bean的銷毀

IOC:控制反轉:將物件的創建權,由Spring管理. DI(依賴注?):在Spring創建物件的程序中,把物件依賴的屬性注?到類中,

Bean定義5種作?域
Spring容器中的bean可以分為5個范圍:
(1)singleton:默認,每個容器中只有一個bean的實體,單例的模式由BeanFactory自身來維護,
(2)prototype:為每一個bean請求提供一個實體,
(3)request:為每一個網路請求創建一個實體,在請求完成以后,bean會失效并被垃圾回收器回收,
(4)session:與request范圍類似,確保每個session中有一個bean的實體,在session過期后,bean會隨之失效,
(5)global-session:全域作用域,global-session和Portlet應用相關,當你的應用部署在Portlet容器中作業時,它包含很多portlet,如果你想要宣告讓所有的portlet共用全域的存盤變數的話,那么這全域變數需要存盤在global-session中,全域作用域與Servlet中的session作用域效果相同,

Spring 中的單例 bean 的執行緒安全問題了解嗎?

大部分時候我們并沒有在系統中使用多執行緒,所以很少有人會關注這個問題,單例 bean 存在執行緒問題,主要是因為當多個執行緒操作同一個物件的時候,對這個物件的非靜態成員變數的寫操作會存在執行緒安全問題,

常見的有兩種解決辦法:

  • 在Bean物件中盡量避免定義可變的成員變數(不太現實),

  • 在類中定義一個ThreadLocal成員變數,將需要的可變成員變數保存在 ThreadLocal 中(推薦的一種方式),

Spring如解決Bean回圈依賴問題?
回圈依賴說的是 A 依賴 B,而 B 又依賴 A,或者是 A 依賴 B,B 依賴 C,而 C 卻依賴 A,
在這里插入圖片描述
在這里插入圖片描述

Spring中回圈依賴場景有:構造器的回圈依賴 屬性的回圈依賴

答:Spring通過三級快取解決了回圈依賴,其中一級快取為單例池(singletonObjects),二級快取為早期曝光物件earlySingletonObjects,三級快取為早期曝光物件工廠(singletonFactories),

當A、B兩個類發生回圈參考時,在A完成實體化后,就使用實體化后的物件去創建一個物件工廠,并添加到三級快取中,如果A被AOP代理,那么通過這個工廠獲取到的就是A代理后的物件,如果A沒有被AOP代理,那么這個工廠獲取到的就是A實體化的物件,

當A進行屬性注入時,會去創建B,同時B又依賴了A,所以創建B的同時又會去呼叫getBean(a)來獲取需要的依賴,此時的getBean(a)會從快取中獲取:

第一步,先獲取到三級快取中的工廠;

第二步,呼叫物件工工廠的getObject方法來獲取到對應的物件,得到這個物件后將其注入到B中,緊接著B會走完它的生命周期流程,包括初始化、后置處理器等,

當B創建完后,會將B再注入到A中,此時A再完成它的整個生命周期,至此,回圈依賴結束!

面試官:”為什么要使用三級快取呢?二級快取能解決回圈依賴嗎?“

答:如果要使用二級快取解決回圈依賴,意味著所有Bean在實體化后就要完成AOP代理,這樣違背了Spring設計的原則,Spring在設計之初就是通過AnnotationAwareAspectJAutoProxyCreator這個后置處理器來在Bean生命周期的最后一步來完成AOP代理,而不是在實體化后就立馬進行AOP代理,

AOP(Aspect-Oriented Programming:面向切面編程)

AOP 是 OOP(面向物件編程)的一種延續補充,傳統的OOP開發中的代碼邏輯是自上而下的,在這程序中會產生些橫切面的問題,而這些橫切面問題又與主業務邏輯關系不大,散落在代碼中難以維護,

AOP就是把這些橫切面問題和主業務邏輯進行分離,達到解耦的?的,提?代碼重?性和開發效率;

AOP 解決了什么問題
通過上面的分析可以發現,AOP 主要用來解決:在不改變原有業務邏輯的情況下,增強橫切邏輯代碼,根本上解耦合,避免橫切邏輯代碼重復,

AOP 為什么叫面向切面編程
:指的是橫切邏輯,原有業務邏輯代碼不動,只能操作橫切邏輯代碼,所以面向橫切邏輯
:橫切邏輯代碼往往要影響的是很多個方法,每個方法如同一個點,多個點構成一個面,這里有一個面的概念

AOP 主要應?場景有:

  • 記錄?志
  • 監控性能
  • 權限控制
  • 事務管理

AOP 核?概念
1、切?(aspect):類是對物體特征的抽象,切?就是對橫切關注點的抽象
2、橫切關注點:對哪些?法進?攔截,攔截后怎么處理,這些關注點稱之為橫切關注點,
3、連接點(joinpoint):被攔截到的點,因為 Spring 只?持?法型別的連接點,所以在Spring 中連接點指的就是被攔截到的?法,實際上連接點還可以是欄位或者構造器,
4、切?點(pointcut):對連接點進?攔截的定義
5、通知(advice):所謂通知指的就是指攔截到連接點之后要執?的代碼,通知分為前置、后置、例外、最終、環繞通知五類,
6、?標物件:代理的?標物件
7、織?(weave):將切?應?到?標物件并導致代理物件創建的程序
8、引?(introduction):在不修改代碼的前提下,引?可以在運?期為類動態地添加?法或欄位,

AOP實作
AOP的實作方式基于IOC,通過beanPostProcessor來自定義bean的結構
主要分為兩大類:
一是采用動態代理技術,利用截取訊息的方式,對該訊息進行裝飾,以取代原有物件行為的執行;
二是采用靜態織入的方式,引入特定的語法創建“方面”,從而使得編譯器可以在編譯期間織入有關“方面”的代碼.

AOP實作的關鍵在于 代理模式,AOP代理主要分為靜態代理和動態代理,靜態代理的代表為AspectJ;動態代理則以Spring AOP為代表,
(1)AspectJ是靜態代理的增強,所謂靜態代理,就是AOP框架會在編譯階段生成AOP代理類,因此也稱為編譯時增強,他會在編譯階段將AspectJ(切面)織入到Java位元組碼中,運行的時候就是增強之后的AOP物件,因此也稱為編譯時增強;
(2)Spring AOP使用的動態代理,所謂的動態代理就是說AOP框架不會去修改位元組碼,而是每次運行時在記憶體中臨時為方法生成一個AOP物件,這個AOP物件包含了目標物件的全部方法,并且在特定的切點做了增強處理,并回呼原物件的方法,因此也被稱為運行時增強,

Spring AOP就是基于動態代理的,如果要代理的物件,實作了某個介面,那么Spring AOP會使用JDK Proxy,去創建代理物件,而對于沒有實作介面的物件,就無法使用 JDK Proxy 去進行代理了,這時候Spring AOP會使用Cglib ,這時候Spring AOP會使用 Cglib 生成一個被代理物件的子類來作為代理

①JDK動態代理只提供介面的代理,不支持類的代理,核心InvocationHandler介面和Proxy類, InvocationHandler 通過invoke()方法反射來呼叫目標類中的代碼,動態地將橫切邏輯和業務編織在一 起;接著,Proxy利用 InvocationHandler動態創建一個符合某一介面的的實體, 生成目標類的代理對 象,

②如果代理類沒有實作 InvocationHandler 介面,那么Spring AOP會選擇使用CGLIB來動態代理目 標類,CGLIB(Code Generation Library),是一個代碼生成的類別庫,可以在運行時動態的生成指定類 的一個子類物件,并覆寫其中特定方法并添加增強代碼,從而實作AOP,CGLIB是通過繼承的方式做的動態代 理,因此如果某個類被標記為final,那么它是無法使用CGLIB做動態代理的,

如下圖所示:在這里插入圖片描述
在這里插入圖片描述(3)靜態代理與動態代理區別在于生成AOP代理物件的時機不同,相對來說AspectJ的靜態代理方式具有更好的性能,但是AspectJ需要特定的編譯器進行處理,而Spring AOP則無需特定的編譯器處理,

jdk動態代理

  • 通過bind?法建?代理與真實物件關系,通過Proxy.newProxyInstance(target)?成代理物件
  • 代理物件通過反射invoke?法實作調?真實物件的?法

動態代理與靜態代理區別

  • 靜態代理,程式運?前代理類的.class?件就存在了;
  • 動態代理:在程式運?時利?反射動態創建代理物件<復?性,易?性,更加集中都調?invoke>

CGLIB與JDK動態代理區別

  • Jdk必須提供接?才能使?;
  • CGLIB不需要,只要?個?抽象類就能實作動態代理

Spring 中使?了哪些設計模式?
??模式: spring中的BeanFactory就是簡單??模式的體現,根據傳?唯?的標識來獲得bean物件;
單例模式: 提供了全域的訪問點BeanFactory;
代理模式: AOP功能的原理就使?代理模式(1、JDK動態代理,2、CGLib位元組碼?成技術代理,)
裝飾器模式: 依賴注?就需要使?BeanWrapper;
觀察者模式: spring中Observer模式常?的地?是listener的實作,如ApplicationListener,
策略模式: Bean的實體化的時候決定采?何種?式初始化bean實體(反射或者CGLIB動態位元組碼?成)

Spring設計模式推薦閱讀:https://snailclimb.gitee.io/javaguide/#/docs/system-design/framework/spring/Spring-Design-Patterns?id=%e6%8e%a7%e5%88%b6%e5%8f%8d%e8%bd%acioc%e5%92%8c%e4%be%9d%e8%b5%96%e6%b3%a8%e5%85%a5di

Spring 事務(基于AOP實作)在這里插入圖片描述

主流程介紹
眾所周知,Spring事務采用AOP的方式實作,我們從TransactionAspectSupport這個類開始分析,

  1. 獲取事務的屬性(@Transactional注解中的配置)
  2. 加載配置中的TransactionManager.
  3. 獲取收集事務資訊TransactionInfo
  4. 執行目標方法
  5. 出現例外,嘗試處理,
  6. 清理事務相關資訊
  7. 提交事務
//1. 獲取@Transactional注解的相關引數
TransactionAttributeSource tas = getTransactionAttributeSource();
// 2. 獲取事務管理器
	final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
	final PlatformTransactionManager tm = determineTransactionManager(txAttr);
	final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

	if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
		// Standard transaction demarcation with getTransaction and commit/rollback calls.
		// 3. 獲取TransactionInfo,包含了tm和TransactionStatus
		TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
		Object retVal = null;
		try {
			// This is an around advice: Invoke the next interceptor in the chain.
			// This will normally result in a target object being invoked.
			// 4.執行目標方法
			retVal = invocation.proceedWithInvocation();
		}
		catch (Throwable ex) {
		   //5.回滾
			// target invocation exception
			completeTransactionAfterThrowing(txInfo, ex);
			throw ex;
		}
		finally {
		  // 6. 清理當前執行緒的事務相關資訊
			cleanupTransactionInfo(txInfo);
		}
		// 提交事務
		commitTransactionAfterReturning(txInfo);
		return retVal;
	}

關鍵物件介紹PlatformTransactionManager

TransactionManager是做什么的?它保存著當前的資料源連接,對外提供對該資料源的事務提交回滾操作介面,同時實作了事務相關操作的方法,一個資料源DataSource需要一個事務管理器,
屬性:DataSource
內部核心方法:
public commit 提交事務
public rollback 回滾事務
public getTransaction 獲得當前事務狀態
protected doSuspend 掛起事務
protected doBegin 開始事務,主要是執行了JDBC的con.setAutoCommit(false)方法,同時處理了很多和資料庫連接相關的ThreadLocal變數,
protected doCommit 提交事務
protected doRollback 回滾事務
protected doGetTransaction() 獲取事務資訊
final getTransaction 獲取事務狀態

@Nullable
	protected PlatformTransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
		// Do not attempt to lookup tx manager if no tx attributes are set
		if (txAttr == null || this.beanFactory == null) {
			return getTransactionManager();
		}

		String qualifier = txAttr.getQualifier();
		//如果指定了Bean則取指定的PlatformTransactionManager型別的Bean
		if (StringUtils.hasText(qualifier)) {
			return determineQualifiedTransactionManager(this.beanFactory, qualifier);
		}
		//如果指定了Bean的名稱,則根據bean名稱獲取對應的bean
		else if (StringUtils.hasText(this.transactionManagerBeanName)) {
			return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
		}
		else {
		// 默認取一個PlatformTransactionManager型別的Bean
			PlatformTransactionManager defaultTransactionManager = getTransactionManager();
			if (defaultTransactionManager == null) {
				defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
				if (defaultTransactionManager == null) {
					defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
					this.transactionManagerCache.putIfAbsent(
							DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
				}
			}
			return defaultTransactionManager;
		}
	}

Spring 管理事務的方式有幾種?

編程式事務,在代碼中硬編碼,(不推薦使用)
宣告式事務,在組態檔中配置(推薦使用)

宣告式事務又分為兩種:

  • 基于XML的宣告式事務
  • 基于注解的宣告式事務

Spring 事務中的隔離級別有哪幾種?

TransactionDefinition 介面中定義了五個表示隔離級別的常量:

?TransactionDefinition.ISOLATION_DEFAULT: 使用后端資料庫默認的隔離級別,Mysql 默認采用的 REPEATABLE_READ隔離級別 Oracle 默認采用的 READ_COMMITTED隔離級別.
?TransactionDefinition.ISOLATION_READ_UNCOMMITTED: 最低的隔離級別,允許讀取尚未提交的資料變更,可能會導致臟讀、幻讀或不可重復讀
?TransactionDefinition.ISOLATION_READ_COMMITTED: 允許讀取并發事務已經提交的資料,可以阻止臟讀,但是幻讀或不可重復讀仍有可能發生
?TransactionDefinition.ISOLATION_REPEATABLE_READ: 對同一欄位的多次讀取結果都是一致的,除非資料是被本身事務自己所修改,可以阻止臟讀和不可重復讀,但幻讀仍有可能發生,
?TransactionDefinition.ISOLATION_SERIALIZABLE: 最高的隔離級別,完全服從ACID的隔離級別,所有的事務依次逐個執行,這樣事務之間就完全不可能產生干擾,也就是說,該級別可以防止臟讀、不可重復讀以及幻讀,但是這將嚴重影響程式的性能,通常情況下也不會用到該級別,

Spring 事務中哪幾種事務傳播行為?

支持當前事務的情況:

?TransactionDefinition.PROPAGATION_REQUIRED: 如果當前存在事務,則加入該事務;如果當前沒有事務,則創建一個新的事務,
?TransactionDefinition.PROPAGATION_SUPPORTS: 如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式繼續運行,
?TransactionDefinition.PROPAGATION_MANDATORY: 如果當前存在事務,則加入該事務;如果當前沒有事務,則拋出例外,(mandatory:強制性)

不支持當前事務的情況:

?TransactionDefinition.PROPAGATION_REQUIRES_NEW: 創建一個新的事務,如果當前存在事務,則把當前事務掛起,
?TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事務方式運行,如果當前存在事務,則把當前事務掛起,
?TransactionDefinition.PROPAGATION_NEVER: 以非事務方式運行,如果當前存在事務,則拋出例外,

其他情況:

?TransactionDefinition.PROPAGATION_NESTED: 如果當前存在事務,則創建一個事務作為當前事務的嵌套事務來運行;如果當前沒有事務,則該取值等價于TransactionDefinition.PROPAGATION_REQUIRED,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/3246.html

標籤:其他

上一篇:作業系統概論【六】- - I/O設備管理

下一篇:演算法案例分析—字串模式匹配演算法

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more