spring源码之事务中篇

 

前言

前面对事务的一些概念性知识进行了总结分析,接下来这章会对spring事务这块的源码进行分析。

概述

在进行AOP分析时,我们把其分析两个过程

  • 初始化时的特殊处理
  • 依赖注入时的特殊处理

事务这块也是基于AOP的,我们也分为两块进行分析,对于一些AOP中提到过的分析,这里会一略而过。

初始化时的特殊处理

  • 根据我们对于AOP的分析知道了,先要去META-INF的spring.handlers找到相应的处理类TxNamespaceHandler,主要是注册了三个解析类
    • TxAdviceBeanDefinitionParser解析器,用于解析<tx:advice>及下面的标签
    • AnnotationDrivenBeanDefinitionParser用于解析<tx:annotation-driven>标签
    • JtaTransactionManagerBeanDefinitionParser(),用于处理分布式事务,可以参照最后的链接进行了解,这里不再进行源码的分析
http\://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler  
//TxNamespaceHandler的整个类,这里的属性和方法都挺重要的,后面的分析从这里开始
//属性这两个值是使用注解事务时起作用的
//注册了三个解析器
public class TxNamespaceHandler extends NamespaceHandlerSupport {

    static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";

    static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";


    static String getTransactionManagerName(Element element) {
        return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ?
                element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME);
    }


    @Override
    public void init() {
        registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
        registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
        registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
    }

}
  • 先从上面注册的AnnotationDrivenBeanDefinitionParser分析,通过AOP的分析知道了,读取配置文件中的

  <tx:annotation-driven transaction-manager="transactionManager"/>,会在这个解析器的parse方法进行解析

    • 注册监听工厂类,最后就是注册了监听器,后面会在整个refresh方法的分析中,说到监听器这块    
    • 根据model判断是否选择aspectj人方法,正常开发中一般不用,LZ也没有跟过源码
    • 正常不会配置model,即都是使用代理的方式,下面对这个进行分析    
//AnnotationDrivenBeanDefinitionParser类的方法
//选择用什么方法进行处理,aspectj或者proxy,正常开发使用
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; }
  •  这里就是整个初始化的特殊处理,分为两部分
    • 注册InfrastructureAdvisorAutoProxyCreator的BeanDefinition,其实就是一个后置处理器,用于依赖注入的初始化阶段(AOP分析中有说过AspectJAwareAdvisorAutoProxyCreator)
    • 注册AnnotationTransactionAttributeSource、TransactionInterceptor、BeanFactoryTransactionAttributeSourceAdvisor三个的BeanDefinition。以及最后注册一个包含这个三个的复杂对象

   下面两个可以注意下:

    • registerTransactionManager这个方法可以跟进去看下,transaction-manager属性如果没有指定的话,它的默认值就是transactionManager
    • advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
      advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);

      这两个方法,把上面的三个BeanDefinition联系起来了,也就是说我们在getBean BeanFactoryTransactionAttributeSourceAdvisor时,其它两个对象也会创建起来。

//AnnotationDrivenBeanDefinitionParser类的方法
//配置动态代理创建类
public
static void configureAutoProxyCreator(Element element, ParserContext parserContext) { AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element); 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); String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef); // Create the TransactionInterceptor definition. RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class); interceptorDef.setSource(eleSource); interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registerTransactionManager(element, interceptorDef); interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName)); String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef); // Create the TransactionAttributeSourceAdvisor definition. RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class); advisorDef.setSource(eleSource); advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName)); advisorDef.getPropertyValues().add("adviceBeanName", interceptorName); if (element.hasAttribute("order")) { advisorDef.getPropertyValues().add("order", element.getAttribute("order")); } 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); } }
  •  注册InfrastructureAdvisorAutoProxyCreator的beanDefiniton,同AOP一样,这个是后面依赖注入的核心
    • registerAutoProxyCreatorIfNecessary是去注册InfrastructureAdvisorAutoProxyCreator,要注意的是在AOP时,我们分析过registerOrEscalateApcAsRequired这个方法,它只会向容器中注册一个优先级高的internalAutoProxyCreator,所以如果配置文件中有<aop:aspectj-autoproxy/>或AOP中提到的配置,都不会向容器中注册InfrastructureAdvisorAutoProxyCreator。而是使用AnnotationAwareAspectJAutoProxyCreator或AspectJAwareAdvisorAutoProxyCreator.class。可以去看下类继承关系,这三个类都AbstractAdvisorAutoProxyCreator的子类,对于这里来说,处理逻辑是一样的,只是后两个优先级更高。
    • 设置proxy-target-class和expose-proxy属性到BeanDefinitioin
    • 如果使用的是InfrastructureAdvisorAutoProxyCreator,这里会注册一个复杂对象
//AopNamespaceUtils类的方法
//注册InfrastructureAdvisorAutoProxyCreator类的beanDefinition
public
static void registerAutoProxyCreatorIfNecessary( ParserContext parserContext, Element sourceElement) { BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); registerComponentIfNecessary(beanDefinition, parserContext); }
//AopConfigUtils类的方法
public
static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) { return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source); }
//AopConfigUtils类的方法
//AOP分析中已经介绍过

private
static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); if (!cls.getName().equals(apcDefinition.getBeanClassName())) { int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } return null; } RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }

 

总结

阅读完AOP,这块的代码还是简单的。下篇再接着对注入过程的进行源码分析

参考链接

  • https://www.cnblogs.com/zjstar12/archive/2012/06/17/2552710.html(jta分布式事务)
  • http://www.linkedkeeper.com/detail/blog.action?bid=1045(事务源码分析)

 

转载于:https://www.cnblogs.com/lucas2/p/9324712.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值