首頁 > 軟體

Spring深入刨析宣告式事務註解的原始碼

2022-07-16 14:00:45

宣告式事務很方便,尤其純註解模式,僅僅幾個註解就能控制事務了

思考:這些註解都做了什麼?好神奇!

@EnableTransactionManagement @Transactional

1、@EnableTransactionManagement

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

@EnableTransactionManagement 註解使用@Import 標籤引入了TransactionManagementConfigurationSelector類,這個類又向容器中匯入了兩個重要的元件

2、載入事務控制元件

2.1、AutoProxyRegistrar

AutoProxyRegistrar 類的 registerBeanDefinitions ⽅法中⼜註冊了⼀個元件

進入AopConfigUtils.registerAutoProxyCreatorIfNecessary 方法

發現最終,註冊了⼀個叫做 InfrastructureAdvisorAutoProxyCreator 的 Bean,而這個類是AbstractAutoProxyCreator 的子類,實現了 SmartInstantiationAwareBeanPostProcessor 介面

public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

繼承體系結構圖如下

它實現了SmartInstantiationAwareBeanPostProcessor,說明這是⼀個後置處理器,而且跟spring AOP 開啟@EnableAspectJAutoProxy 時註冊的 AnnotationAwareAspectJProxyCreator實

現的是同⼀個介面,所以說,宣告式事務是 springAOP 思想的⼀種應用

2.2、ProxyTransactionManagementConfiguration 元件

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
// 事務增強器
        BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
// 向事務增強器中注⼊ 屬性解析器 transactionAttributeSource
        advisor.setTransactionAttributeSource(transactionAttributeSource());
// 向事務增強器中注⼊ 事務攔截器 transactionInterceptor
        advisor.setAdvice(transactionInterceptor());
        if (this.enableTx != null) {
            advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
        }
        return advisor;
    }
    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
// 屬性解析器 transactionAttributeSource
    public TransactionAttributeSource transactionAttributeSource() {
        return new AnnotationTransactionAttributeSource();
    }
    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
// 事務攔截器 transactionInterceptor
    public TransactionInterceptor transactionInterceptor() {
        TransactionInterceptor interceptor = new TransactionInterceptor();
        interceptor.setTransactionAttributeSource(transactionAttributeSource());
        if (this.txManager != null) {
            interceptor.setTransactionManager(this.txManager);
        }
        return interceptor;
    }
}

ProxyTransactionManagementConfiguration是⼀個容器設定類,註冊了⼀個元件transactionAdvisor,稱為事務增強器,然後在這個事務增強器中又注入了兩個屬性:transactionAttributeSource,即屬性解析器transactionAttributeSource 和 事務攔截器transactionInterceptor

屬性解析器 AnnotationTransactionAttributeSource 部分原始碼如下

屬性解析器有⼀個成員變數是annotationParsers,是⼀個集合,可以新增多種註解解析器(TransactionAnnotationParser),我們關注 Spring 的註解解析器,部分原始碼如下

屬性解析器的作⽤之⼀就是⽤來解析@Transaction註解

TransactionInterceptor 事務攔截器,部分原始碼如下

2.3、上述元件如何關聯起來的

  • 事務攔截器實現了MethodInterceptor介面,追溯⼀下上面提到的InfrastructureAdvisorAutoProxyCreator後置處理器,它會在代理物件執行目標方法的時候獲取其攔截器鏈,而攔截器鏈就是這個TransactionInterceptor,這就把這兩個元件聯絡起來;
  • 構造方法傳⼊PlatformTransactionManager(事務管理器)、TransactionAttributeSource(屬性解析器),但是追溯一下上⾯貼的ProxyTransactionManagementConfiguration的原始碼,在註冊事務攔截器的時候並沒有呼叫這個帶參構造方法,而是呼叫的無參構造方法,然後再呼叫set方法注⼊這兩個屬性,效果⼀樣。

2.4、invokeWithinTransaction⽅法

部分原始碼如下(關注1、2、3、4 標註處)

到此這篇關於Spring深入刨析宣告式事務註解的原始碼的文章就介紹到這了,更多相關Spring宣告式事務註解內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com