Spring 常見面試題

Spring 常見面試題

Spring 八股文

說說你對Spring的理解?

Spring 使創建 Java 企業應用程序變得更加容易。

它提供了在企業環境中接受 Java 語言所需的一切,並支持 Groovy 和 Kotlin 作爲 JVM 上的替代語言,並可根據應用程序的需要靈活地創建多種體系結構。 從 Spring Framework 5.0 開始,Spring 需要 JDK8 (Java SE 8+),並且已經爲 JDK9 提供了現成的支持。

Spring支持各種應用場景,在大型企業中, 應用程序通常需要運行很長時間,而且必須運行在 jdk 和應用服務器上,這種場景開發人員無法控制其升級週期。 其他可能作爲一個單獨的 jar 嵌入到服務器去運行,也有可能在雲環境中。還有一些可能是不需要服務器的獨立應用程序(如批處理或集成的工作任務)。

Spring 是開源的。它擁有一個龐大而且活躍的社區,提供不同範圍的,真實用戶的持續反饋。這也幫助 Spring 不斷地改進,不斷髮展。

你覺得Spring的核心是什麼?

Spring 是一個 IOCAOP容器 框架。

  • IoC:控制反轉
  • AOP:面向切面編程
  • 容器:包含並管理應用對象的生命週期

說一下Spring的優勢?

  1. Spring通過DI、AOP和消除樣板式代碼來簡化企業級Java開發。
  2. Spring框架之外還存在一個構建在覈心框架之上的龐大生態圈,它將Spring 擴展到不同的領域,如Web服務、REST、移動開發以及NoSQL。
  3. 低侵入式設計,代碼的污染極低。
  4. 獨立於各種應用服務器,基於Spring框架的應用,可以真正實現Write Once,Run Anywhere的承諾。
  5. Spring的IoC容器降低了業務對象替換的複雜性,提高了組件之間的解耦。
  6. Spring的AOP支持允許將一些通用任務如安全、事務、日誌等進行集中式處理,從而提供了更好的複用。
  7. Spring的ORM和DAO提供了與第三方持久層框架的的良好整合,並簡化了底層的數據庫訪問。
  8. Spring的高度開放性,並不強制應用完全依賴於Spring,開發者可自由選用Spring框架的部分或全部。

Spring是如何簡化開發的?

  1. 基於POJO的輕量級和最小侵入性編程。
  2. 通過依賴注入和麪向接口實現松耦合。
  3. 基於切面和慣例進行聲明式編程。
  4. 通過切面和模板減少樣板式代碼。

Spring 核心

Spring支持的bean作用域有哪些?

  1. singleton:使用該屬性定義Bean時,IOC容器僅創建一個Bean實例,IOC容器每次返回的是同一個Bean實例。
  2. prototype:使用該屬性定義Bean時,IOC容器可以創建多個Bean實例,每次返回的都是一個新的實例。
  • request:該屬性僅對HTTP請求產生作用,使用該屬性定義Bean時,每次HTTP請求都會創建一個新的Bean,適用於WebApplicationContext環境。
  1. session:該屬性僅用於HTTP Session,同一個Session共享一個Bean實例,不同Session使用不同的實例。
  2. global-session:該屬性僅用於HTTP Session,同session作用域不同的是,所有的Session共享一個Bean實例。

Spring中的單例bean是線程安全的麼?

Spring中的Bean對象默認是單例的,框架並沒有對bean進行多線程的封裝處理。

如果Bean是有狀態的,那麼就需要開發人員自己來保證線程安全的保證,最簡單的辦法就是改變bean的作用域把singleton改成prototype,這樣每次請求bean對象就相當於是創建新的對象來保證線程的安全。

Bean有狀態就是有數據存儲的功能,無狀態就是不會存儲數據。你想一下,我們的controller,service和dao本身並不是線程安全的,只是調用裏面的方法,而且多線程調用一個實例的方法,會在內存中複製遍歷,這是自己線程的工作內存,是最安全的。

因此在進行使用的時候,不要在bean中聲明任何有狀態的實例變量或者類變量,如果必須如此,也推薦大家使用ThreadLocal把變量變成線程私有,如果bean的實例變量或者類變量需要在多個線程之間共享,那麼就只能使用synchronized,lock,cas等這些實現線程同步的方法了。

Spring中bean的自動裝配有哪些方式?

bean的自動裝配指的是,bean的屬性值在進行注入的時候,通過某種特定的規則和方式去容器中查找,並設置到具體的對象屬性中,主要有五種方式:

  1. no:缺省情況下,自動配置是通過“ref”屬性手動設定,在項目中最常用
  2. byName:根據屬性名稱自動裝配。如果一個bean的名稱和其他bean屬性的名稱是一樣的,將會自裝配它。
  3. byType:按數據類型自動裝配,如果bean的數據類型是用其它bean屬性的數據類型,兼容並自動裝配它。
  4. constructor:在構造函數參數的byType方式。
  5. autodetect:如果找到默認的構造函數,使用“自動裝配用構造”; 否則,使用“按類型自動裝配”。

說說你對Spring IOC的理解?

總:

控制反轉:原來的對象是由使用者來進行控制,有了Spring之後,可以把整個對象交給Spring來幫我們進行管理。

DI:依賴注入,把對應的屬性的值注入到具體的對象中,@Autowired,populateBean完成屬性值的注入。

容器:存儲對象,使用map結構來存儲,在Spring中一般存在三級緩存,singletonObjects存放完整的bean對象,整個bean的生命週期,從創建到使用到註銷的過程全部都是由容器來管理(bean的生命週期)。

分:

  1. 一般聊IOC容器的時候要涉及到容器的創建過程(BeanFactory、DefaultListableBeanFactory),向bean工廠中設置一些參數(BeanPostProcessor,Aware接口的子類)等等屬性。
  2. 加載並解析bean對象,準備要創建的bean對象的定義對象BeanDefinition(xml或者註解的解析過程)。
  3. BeanFactoryPostProcessor的處理,此處是擴展點,PlaceholderConfigurerSupport,ConfigurationClassPostProcessor。
  4. BeanPostProcessor的註冊功能,方便後續對bean對象完成具體的擴展功能。
  5. 通過反射的方式將BeanDefinition對象實例化成具體的bean對象。
  6. bean對象的初始化過程(填充屬性,調用aware子類的方法,調用BeanPostProcessor前置處理方法,調用init-method方法,調用BeanPostProcessor的後置處理方法)。
  7. 生成完整的bean對象,通過getBean方法可以直接獲取。
  8. 銷燬過程。

面試官,這是我對ioc的整體理解,包含了一些詳細的處理過程,您看一下有什麼問題,可以指點我一下,您有什麼想問的?

具體的細節我記不太清了,但是Spring中的bean都是通過反射的方式生成的,同時其中包含了很多的擴展點,比如最常用的對BeanFactory的擴展,對bean的擴展(對佔位符的處理),我們在公司對這方面的使用是比較多的,除此之外,ioc中最核心的也就是填充具體bean的屬性和生命週期。

談一下Spring IOC的底層實現?

底層實現:工作原理、實現過程、數據結構、流程、設計思想、設計模式

你對他的理解和你瞭解的實現過程

反射、工廠、設計模式、關鍵的幾個方法。。。

createBeanFactory,getBean,doGetBean,createBean,doCreateBean,createBeanInstance (getDeclaredConstructor,newInstance),populateBean,initializingBean

  1. 先通過createBeanFactory創建出一個Bean工廠(DefaultListableBeanFactory)。
  2. 開始循環創建對象,因爲容器中的bean默認都是單例的,所以優先通過getBean,doGetBean從容器中查找。
  3. 找不到的話,通過createBean,doCreateBean方法,以反射的方式創建對象。一般情況下使用的是無參的構造方法(getDeclaredConstructor,newInstance)。
  4. 進行對象的屬性填充populateBean。
  5. 進行其他的初始化操作(initializingBean)。

描述一下bean的生命週期?

bean的生命週期.png

背圖:記住圖中的流程。
在表述的時候不要只說圖中有的關鍵點,要學會擴展描述。

  1. 實例化bean:通過反射的方式進行對象的創建,此時創建的只是在堆空間中申請空間,屬性都是默認值。
  2. 設置對象屬性:給對象中的屬性進行值的設置工作,populateBean(),循環依賴的問題(三級緩存)。
  3. 檢查Aware相關接口並設置相關依賴:如果對象中需要引用容器內部的對象,那麼需要調用aware接口的子類方法來進行統一設置。invokeAwareMethod(完成BeanName、BeanFactory、BeanClassLoader對象的屬性設置)。
  4. BeanPostProcessor的前置處理:對生成的bean對象進行前置的處理工作,使用比較多的有(ApplicationContextPostProcessor,設置ApplicationContext,Environment,ResourceLoader,EmbeddValueResolver等對象)。
  5. 檢查是否是InitializingBean的子類來決定是否調用afterPropertiesSet方法:判斷當前bean對象是否設置了InitializingBean接口,然後進行屬性的設置等基本工作。
  6. 檢查是否配置有自定義的init-method方法:如果當前bean對象定義了初始化方法,那麼在此處調用初始化方法。
  7. BeanPostProcessor的後置處理:對生成的bean對象進行後置的處理工作,spring的aop就是在此處實現的
  8. 註冊必要的Destruction相關的回調接口:爲了方便對象的銷燬,在此處調用註銷的回調接口,方便對象進行銷燬操作。
  9. 獲取並使用bean對象:通過容器來獲取對象並進行使用。
  10. 是否實現DisposableBean接口:判斷是否實現了DisposableBean接口,並調用具體的方法來進行對象的銷燬工作。
  11. 是否配置有自定義的destroy方法:如果當前bean對象定義了銷燬方法,那麼在此處調用銷燬方法。

Spring是如何解決循環依賴問題的?

三級緩存,提前暴露對象,aop。
總:什麼是循環依賴問題,A依賴B,B依賴A。
分:先說明bean的創建過程,實例化、初始化(填充屬性)。

  1. 先創建A對象,實例化A對象,此時A對象中的b屬性爲空,填充屬性b。
  2. 從容器中查找B對象,如果找到了,直接賦值不存在循環依賴的問題(不通),找不到直接創建B對象。
  3. 實例化B對象,此時B對象中a的屬性爲空,填充屬性a。
  4. 從容器中查找A對象,找不到,直接創建。

循環依賴產生原因.png

形成閉環的原因

此時,如果仔細琢磨的話,會發現A對象是存在的,只不過此時的A對象不是一個完成的狀態,只完成了實例化但是未完成初始化,如果程序在調用過程中,擁有了某個對象的引用,能否在後期給他完成賦值操作,可以優先把非完整狀態的對象優先賦值,等待後續操作來完成賦值,相當於提前暴露了某個不完整對象的引用,所以解決問題的核心在於實例化和初始化分開操作,這也是解決循環依賴問題的關鍵

當所有的對象都完成實例化和初始化操作之後,還要把完整對象放到容器中,此時在容器中存在對象的幾個狀態:完成實例化-但未完成初始化、完整狀態,因爲都在容器中,所以要使用不同的map結構來進行存儲,此時就有了一級緩存和二級緩存,如果一級緩存中有了,那麼二級緩存中就不會存在同名的對象,因爲他們的查找順序是1,2,3這樣的方式來查找的。一級緩存中放的是完整對象,二級緩存中放的是非完整對象。

爲什麼需要三級緩存?

三級緩存的value類型是ObjectFactory (Map<String, ObjectFactory<?>>),是一個函數式接口,存在的意義是保證在整個容器的運行過程中同名的bean對象只能有一個。

如果一個對象需要被代理,或者說需要生成代理對象,那麼要不要優先生成一個普通對象?要

普通對象和代理對象是不能同時出現在容器中的,因此當一個對象需要被代理的時候,就要使用代理對象覆蓋掉之前的普通對象,在實際的調用過程中,是沒有辦法確定什麼時候對象被使用的,所以就要求當某個對象被調用的時候,優先判斷此對象是否需要被代理,類似於一種回調機制的實現,因此傳入lambda表達式的時候,可以通過lambda表達式來執行對象的覆蓋過程,具體方法爲getEarlyBeanReference(Object bean, String beanName);。

因此,所有的bean對象在創建的時候都要優先放到三級緩存中,在後續的使用過程中,如果需要被代理則返回代理對象,如果不需要被代理,則直接返回普通對象。

緩存的放置時間和刪除時間?

  • 三級緩存:createBeanInstance之後,核心方法 addSingletonFactory。
  • 二級緩存:第一次從三級緩存確認對象是代理對象還是普通對象的時候,同時刪除三級緩存,核心方法 getSingleton。
  • 一級緩存:生成完整對象之後放到一級緩存,刪除二三級緩存,核心方法 addSingleton。

Spring的AOP的底層原理實現?

動態代理
aop是ioc的一個擴展功能,現有的ioc,再有的aop,只是在ioc整個流程中新增的一個擴展點而已:BeanPostProcessor後置處理

  • 總:aop概念、應用場景、動態代理
  • 分:bean的創建過程中有一個步驟可以對bean進行擴展實現,aop本身就是一個擴展功能,所以在BeanPostProcessor的後置處理方法中來進行實現:
    1. 代理對象的創建過程(advice,切面,切點)。
    2. 通過jdk或者cglib的方式來生成代理對象。
    3. 在執行方法調用的時候,會調用到生成的字節碼文件中,直接會找到DynamicAdvisoredInterceptor類中的intercept方法,從此方法開始執行。
    4. 根據之前定義好的通知來生成攔截器鏈。
    5. 從攔截器鏈中依次獲取每一個通知開始進行執行,在執行過程中,爲了方便找到下一個通知是哪個,會有一個CglibMethodInvocation的對象,找的時候是從-1的位置以此開始查找並執行的。

八股文

AOP全稱叫做 Aspect Oriented Programming 面向切面編程。它是爲解耦而生的,解耦是程序員編碼開發過程中一直追求的境界,AOP在業務類的隔離上,絕對是做到了解耦,在這裏面有幾個核心的概念:

  • 切面(Aspect): 指關注點模塊化,這個關注點可能會橫切多個對象。事務管理是企業級Java應用中有關橫切關注點的例子。 在Spring AOP中,切面可以使用通用類基於模式的方式(schema-based approach)或者在普通類中以@Aspect註解(@AspectJ 註解方式)來實現。

  • 連接點(Join point): 在程序執行過程中某個特定的點,例如某個方法調用的時間點或者處理異常的時間點。在Spring AOP中,一個連接點總是代表一個方法的執行。

  • 通知(Advice): 在切面的某個特定的連接點上執行的動作。通知有多種類型,包括“around”, “before” and “after”等等。通知的類型將在後面的章節進行討論。 許多AOP框架,包括Spring在內,都是以攔截器做通知模型的,並維護着一個以連接點爲中心的攔截器鏈。

  • 切點(Pointcut): 匹配連接點的斷言。通知和切點表達式相關聯,並在滿足這個切點的連接點上運行(例如,當執行某個特定名稱的方法時)。切點表達式如何和連接點匹配是AOP的核心:Spring默認使用AspectJ切點語義。

  • 引入(Introduction): 聲明額外的方法或者某個類型的字段。Spring允許引入新的接口(以及一個對應的實現)到任何被通知的對象上。例如,可以使用引入來使bean實現 IsModified接口, 以便簡化緩存機制(在AspectJ社區,引入也被稱爲內部類型聲明(inter))。

  • 目標對象(Target object): 被一個或者多個切面所通知的對象。也被稱作被通知(advised)對象。既然Spring AOP是通過運行時代理實現的,那麼這個對象永遠是一個被代理(proxied)的對象。

  • AOP代理(AOP proxy):AOP框架創建的對象,用來實現切面契約(aspect contract)(包括通知方法執行等功能)。在Spring中,AOP代理可以是JDK動態代理或CGLIB代理。

  • 織入(Weaving): 把切面連接到其它的應用程序類型或者對象上,並創建一個被被通知的對象的過程。這個過程可以在編譯時(例如使用AspectJ編譯器)、類加載時或運行時中完成。 Spring和其他純Java AOP框架一樣,是在運行時完成織入的。

    這些概念都太學術了,如果更簡單的解釋呢,其實非常簡單:

    任何一個系統都是由不同的組件組成的,每個組件負責一塊特定的功能,當然會存在很多組件是跟業務無關的,例如日誌、事務、權限等核心服務組件,這些核心服務組件經常融入到具體的業務邏輯中,如果我們爲每一個具體業務邏輯操作都添加這樣的代碼,很明顯代碼冗餘太多,因此我們需要將這些公共的代碼邏輯抽象出來變成一個切面,然後注入到目標對象(具體業務)中去,AOP正是基於這樣的一個思路實現的,通過動態代理的方式,將需要注入切面的對象進行代理,在進行調用的時候,將公共的邏輯直接添加進去,而不需要修改原有業務的邏輯代碼,只需要在原來的業務邏輯基礎之上做一些增強功能即可。

BeanFactory與FactoryBean有什麼區別?

  • 相同點:都是用來創建bean對象的。
  • 不同點:使用BeanFactory創建對象的時候,必須要嚴格遵循bean的生命週期的流程,太複雜了,如果想要簡單的自定義某個對象的創建,同時創建完成的對象想交給Spring來管理,那麼就需要實現FactoryBean接口了
public interface FactoryBean<T> {
    ...
    
    // 自定義創建對象的過程(new、反射、動態代理)
    @Nullable
	T getObject() throws Exception;
    
    // 獲取返回對象的類型
    @Nullable
	Class<?> getObjectType();
	
    // 是否是單例對象
    default boolean isSingleton() {
		        return true;
	}

}

BeanFactory和ApplicationContext有什麼區別?

image

相同點:

  • Spring提供了兩種不同的IOC容器,一個是BeanFactory,另外一個是ApplicationContext,它們都是Java interface,ApplicationContext繼承於BeanFactory(ApplicationContext繼承ListableBeanFactory。
  • 它們都可以用來配置XML屬性,也支持屬性的自動注入。
  • 而ListableBeanFactory繼承BeanFactory,BeanFactory和ApplicationContext 都提供了一種方式,使用getBean("beanName")獲取bean

不同點:

  • 當你調用getBean()方法時,BeanFactory僅實例化bean,而ApplicationContext 在啓動容器的時候實例化單例bean,不會等待調用getBean()方法時再實例化。
  • BeanFactory不支持國際化,即i18n,但ApplicationContext提供了對它的支持。
  • BeanFactory與ApplicationContext之間的另一個區別是能夠將事件發佈到註冊爲監聽器的bean。
  • BeanFactory 的一個核心實現是XMLBeanFactory 而ApplicationContext 的一個核心實現是ClassPathXmlApplicationContext,Web容器的環境我們使用WebApplicationContext並且增加了getServletContext 方法。
  • 如果使用自動注入並使用BeanFactory,則需要使用API註冊AutoWiredBeanPostProcessor,如果使用ApplicationContext,則可以使用XML進行配置。
  • 簡而言之,BeanFactory提供基本的IOC和DI功能,而ApplicationContext提供高級功能,BeanFactory可用於測試和非生產使用,但ApplicationContext是功能更豐富的容器實現,應該優於BeanFactory。

Spring中使用了哪些設計模式及應用場景?

  • 工廠模式,在各種BeanFactory以及ApplicationContext創建中都用到了。
  • 模版模式,在各種BeanFactory以及ApplicationContext實現中也都用到了。
  • 代理模式,Spring AOP 利用了 AspectJ AOP實現的! AspectJ AOP 的底層用了動態代理。
  • 策略模式,加載資源文件的方式,使用了不同的方法,比如:ClassPathResourece,FileSystemResource,ServletContextResource,UrlResource但他們都有共同的藉口Resource;在Aop的實現中,採用了兩種不同的方式,JDK動態代理和CGLIB代理。
  • 單例模式,比如在創建bean的時候
  • 觀察者模式,spring中的ApplicationEvent,ApplicationListener,ApplicationEventPublisher。
  • 適配器模式,MethodBeforeAdviceAdapter,ThrowsAdviceAdapter,AfterReturningAdapter。
  • 裝飾者模式,源碼中類型帶Wrapper或者Decorator的都是。

Spring 事務

Spring事務的實現方式及原理是什麼?

在使用Spring框架的時候,可以有兩種事務的實現方式,一種是編程式事務,有用戶自己通過代碼來控制事務的處理邏輯;還有一種是聲明式事務,即通過@Transactional註解來實現。

其實事務的操作本來應該是由數據庫來進行控制,但是爲了方便用戶進行業務邏輯的操作,spring對事務功能進行了擴展實現,一般我們很少會用編程式事務,更多的是通過添加@Transactional註解來進行實現,當添加此註解之後事務的自動功能就會關閉,由spring框架來幫助進行控制。

其實事務操作是AOP的一個核心體現,當一個方法添加@Transactional註解之後,spring會基於這個類生成一個代理對象,會將這個代理對象作爲bean,當使用這個代理對象的方法的時候,如果有事務處理,那麼會先把事務的自動提交給關閉,然後去執行具體的業務邏輯,如果執行邏輯沒有出現異常,那麼代理邏輯就會直接提交,如果出現任何異常情況,那麼直接進行回滾操作,當然用戶可以控制對哪些異常進行回滾操作。

TransactionInterceptor

Spring事務的隔離級別有哪些?

Spring中的事務隔離級別就是數據庫的隔離級別,有以下幾種:

  • read uncommitted:讀未提交
  • read committed:讀已提交
  • repeatable read:可重複讀
  • serializable:串行化

在進行配置的時候,如果數據庫和Spring代碼中的隔離級別不同,那麼以Spring的配置爲主。

Spring事務的傳播機制是什麼?

多個事務方法相互調用時,事務如何在這些方法之間進行傳播,spring中提供了7中不同的傳播特性,來保證事務的正常執行:

  • REQUIRED:默認的傳播特性,如果當前沒有事務,則新建一個事務,如果當前存在事務,則加入這個事務。

  • SUPPORTS:當前存在事務,則加入當前事務,如果當前沒有事務,則以非事務的方式執行。

  • MANDATORY:當前存在事務,則加入當前事務,如果當前事務不存在,則拋出異常。

  • REQUIRED_NEW:創建一個新事務,如果存在當前事務,則掛起該事務。

  • NOT_SUPPORTED:以非事務方式執行,如果存在當前事務,則掛起當前事務。

  • NEVER:不使用事務,如果當前事務存在,則拋出異常。

  • NESTED:如果當前事務存在,則在嵌套事務中執行,否則REQUIRED的操作一樣。

NESTED和REQUIRED_NEW的區別:

REQUIRED_NEW是新建一個事務並且新開始的這個事務與原有事務無關,而NESTED則是當前存在事務時會開啓一個嵌套事務,在NESTED情況下,父事務回滾時,子事務也會回滾,而REQUIRED_NEW情況下,原有事務回滾,不會影響新開啓的事務。

NESTED和REQUIRED的區別:

REQUIRED情況下,調用方存在事務時,則被調用方和調用方使用同一個事務,那麼被調用方出現異常時,由於共用一個事務,所以無論是否catch異常,事務都會回滾,而在NESTED情況下,被調用方發生異常時,調用方可以catch其異常,這樣只有子事務回滾,父事務不會回滾。

某一個事務嵌套另一個事務的時候怎麼辦?
A方法調用B方法,AB方法都有事務,並且傳播特性不同,那麼A如果有異常,B怎麼辦,B如果有異常,A怎麼辦?


事務的傳播特性指的是不同方法的嵌套調用過程中,事務應該如何進行處理,是用同一個事務還是不同的事務,當出現異常的時候會回滾還是提交,兩個方法之間的相關影響,在日常工作中,使用的比較多的是 required,requires_new,nested

  1. 先說事務的不同分類,可以分爲三類:支持當前事務、不支持當前事務、嵌套事務
  2. 如果外層方法是required,內層方法是
  3. 如果外層方法是requires_new,內層方法是,required,requires_new,nested
  4. 如果外層方法是nested,內層方法是,required,requires_new,nested

Spring事務是如何回滾的?

Spring的事務管理是如何實現的?

總:

Spring的事務管理是通過aop來實現的,首先要生成具體的代理對象,然後按照aop的整套流程來執行具體的操作邏輯,正常情況下要通過通知來完成核心功能,但是事務不是通過通知來實現的,而是通過一個TransactionInterceptor來實現的,然後調用invoke來實現具體的邏輯。

分:

  1. 先做準備工作,解析各個方法上事務相關的屬性,根據具體的屬性來判斷是否開始新事務。
  2. 當需要開啓的時候,獲取數據庫連接,關閉自動提交功能,開啓事務。
  3. 執行具體的sql邏輯操作。
  4. 在操作過程中,如果執行失敗了,那麼會通過completeTransactionAfterThrowing來完成事務的回滾操作,回滾的具體邏輯是通過doRollback方法來實現的,實現的時候也是要先獲取連接對象,通過連接對象來進行回滾。
  5. 如果在執行過程中,沒有任何意外情況的發生,那麼通過commitTransactionAfterReturning來完成事務的提交操作,提交的具體邏輯是通過doCommit方法來實現的,實現的時候也是要獲取連接,通過連接對象來提交。
  6. 當事務執行完畢之後需要清除相關的事務信息cleanupTransactionInfo,
    如果要聊的更細緻的話,需要知道TransactionInfo,TransactionStatus。

Spring事務什麼時候會失效?

  1. bean對象沒有被Spring容器管理。
  2. 方法的訪問修飾符不是public。
  3. 自身調用的問題。
  4. 數據源沒有配置事務管理器。
  5. 數據庫不支持事務。
  6. 異常類型錯誤或者配置錯誤。

總結

  1. 面試之前一定要調整好心態,不管你會多少東西,幹就完了,出去面試就一個心態,老子天下第一,讓自己超常發揮。
  2. 得失心不要太重,全中國企業很多,好公司也有很多,沒必要在一棵樹上吊死,你可以有心儀的公司,留到最後,等你準備充分再去。
  3. 找工作永遠不可能準備好,很多人慫,心態不好,不敢出去面試。先按照你的技術儲備嘗試一些公司(我就是來試水的),面試回來之後做總結,做好準備,不斷總結,覆盤,這樣才能成長。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章