spring事務管理源碼解析之namespaceHandler

說在前面spring

本文轉自「天河聊技術」微信公衆號微信

spring事務管理項目開發中都會用到,你們通常用的都是聲明式事務管理,spring也集成jta全局事務管理的支持,用的比較少,本次主要針對聲明式本地事務管理角度進行源碼解析,有好的看法歡迎關注「天河聊技術」微信公衆號,在微信公衆號中找到我本人微信加入技術微信羣進一步交流,大家的支持是我一直寫下去的動力,若是以爲看完對本身有所幫助,也歡迎朋友圈轉發,源碼解析很痛苦,it生涯就是這樣,這種痛苦也叫成長。spa

 

正文代理

事務管理器對象

本地事務基於jdbc的是org.springframework.jdbc.datasource.DataSourceTransactionManagerblog

 

事務註解解析器事務

使用spring的事務管理,要先引入spring-tx包,那就先會加載org.springframework.transaction.config.TxNamespaceHandler,先簡單看下這個類的內容element

registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());

這行代碼是對<tx:annotation-driven"/>標籤的解析。資源

 

進入到這個類的這個方法開發

org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser#parse

public BeanDefinition parse(Element element, ParserContext parserContext) {
//    註冊事務監聽器工廠
      registerTransactionalEventListenerFactory(parserContext);
//    獲取模式屬性
      String mode = element.getAttribute("mode");
      if ("aspectj".equals(mode)) {
         // mode="aspectj"
         registerTransactionAspect(element, parserContext);
      }
      else {
         // mode="proxy"
         AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
      }
      return null;
   }
private void registerTransactionalEventListenerFactory(ParserContext parserContext) {
//    註冊事務監聽器的bean定義
      RootBeanDefinition def = new RootBeanDefinition();
      def.setBeanClass(TransactionalEventListenerFactory.class);
      parserContext.registerBeanComponent(new BeanComponentDefinition(def,
            TransactionManagementConfigUtils.TRANSACTIONAL_EVENT_LISTENER_FACTORY_BEAN_NAME));
   }

這個標籤能夠指定事務實現模式,mode屬性,值是aspectj和proxy兩種,默認是後者。

 

建立自動代理器

AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);

 

進入這個方法

org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer#configureAutoProxyCreator

public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
//       註冊自動代理器
         AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);

//       解析internalTransactionAdvisor beanName
         String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
         if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
            Object eleSource = parserContext.extractSource(element);

            // Create the TransactionAttributeSource definition.
            RootBeanDefinition sourceDef = new RootBeanDefinition(
                  "org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
            sourceDef.setSource(eleSource);
            sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//          註冊事務屬性對象並返回自動生成的beanName
            String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);

            // Create the TransactionInterceptor definition.
            RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
            interceptorDef.setSource(eleSource);
            interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//          註冊事務管理器到事務攔截器bean定義中
            registerTransactionManager(element, interceptorDef);
//          註冊事務屬性資源到事務攔截器bean定義中
            interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
//          註冊事務攔截器bean定義並返回自動生成的beanName
            String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);

            // Create the TransactionAttributeSourceAdvisor definition.建立事務屬性資源通知bean定義
            RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
            advisorDef.setSource(eleSource);
            advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//          把事務屬性資源引用註冊到TransactionAttributeSourceAdvisor bean定義中
            advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
//          添加通知beanName到TransactionAttributeSourceAdvisor bean定義中
            advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
            if (element.hasAttribute("order")) {
               advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
            }
//          註冊TransactionAttributeSourceAdvisor bean定義
            parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);

            CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
            compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
            compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
            compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
            parserContext.registerComponent(compositeDef);
         }
      }
   }
註冊自動代理器
         AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
public static void registerAutoProxyCreatorIfNecessary(
         ParserContext parserContext, Element sourceElement) {

      BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
            parserContext.getRegistry(), parserContext.extractSource(sourceElement));
//    若是須要採用cglib自動代理
      useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
      registerComponentIfNecessary(beanDefinition, parserContext);
   }

 

返回到這個方法

org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser#parse

 

註冊事務切面

// mode="aspectj"
registerTransactionAspect(element, parserContext);
private void registerTransactionAspect(Element element, ParserContext parserContext) {
      String txAspectBeanName = TransactionManagementConfigUtils.TRANSACTION_ASPECT_BEAN_NAME;
      String txAspectClassName = TransactionManagementConfigUtils.TRANSACTION_ASPECT_CLASS_NAME;
      if (!parserContext.getRegistry().containsBeanDefinition(txAspectBeanName)) {
         RootBeanDefinition def = new RootBeanDefinition();
         def.setBeanClassName(txAspectClassName);
         def.setFactoryMethodName("aspectOf");
//       註冊事務管理器到bean定義中
         registerTransactionManager(element, def);
//       註冊事務管理器切面bean定義
         parserContext.registerBeanComponent(new BeanComponentDefinition(def, txAspectBeanName));
      }
   }

說到最後

本次解析僅表明我的看法,僅供參考。

相關文章
相關標籤/搜索