說在前面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)); } }
說到最後
本次解析僅表明我的看法,僅供參考。