Spring Tx源码解析(二)

Spring Tx源码解析(二),第1张

   上一篇 我们介绍了 spring-tx 中的底层抽象,本篇我们一起来看看围绕这些抽象概念 spring-tx 是如何打造出声明式事务的吧。笼统的说, spring-tx-526RELEASE 的实现主要分为两个部分:

这两部分彼此独立又相互成就,并且每个部分都有着大量的源码支撑,本篇我们先来分析 spring-tx 中的AOP部分吧。

   EnableTransactionManagement 注解想必大家都很熟悉了,它是启用 Spring 中注释驱动的事务管理功能的关键。

EnableTransactionManagement 注解的主要作用是向容器中导入 TransactionManagementConfigurationSelector ,至于注解中定义的几个属性在 Spring AOP源码解析 中有过详细分析,这里就不再赘述了。

由于我们并没有使用 AspectJ ,因此导入容器的自然是 ProxyTransactionManagementConfiguration 这个配置类。

  这个配置类的核心是向容器中导入一个类型为 BeanFactoryTransactionAttributeSourceAdvisor 的Bean。这是一个 PointcutAdvisor ,它的 Pointcut 是 TransactionAttributeSourcePointcut , Advice 是 TransactionInterceptor 。

   TransactionAttributeSourcePointcut 利用 TransactionAttributeSource 解析 @Transactional 注解的能力来选取标注了 @Transactional 注解的方法,而 TransactionInterceptor 则根据应用提出的需求(来自对 @Transactional 注解的解析)将方法增强为事务方法,因此 BeanFactoryTransactionAttributeSourceAdvisor 可以识别出那些标注了 @Transactional 注解的方法,为它们应用上事务相关功能。

   TransactionInterceptor 能对方法进行增强,但是它却不知道该如何增强,比如是为方法新开一个独立事务还是沿用已有的事务?什么情况下需要回滚,什么情况下不需要?必须有一个『人』告诉它该如何增强,这个『人』便是 TransactionAttributeSource 。

   @Transactional 注解定义了事务的基础信息,它表达了应用程序期望的事务形态。 TransactionAttributeSource 的主要作用就是解析 @Transactional 注解,提取其属性,包装成 TransactionAttribute ,这样 TransactionInterceptor 的增强便有了依据。

前面我们已经见过, spring-tx 使用 AnnotationTransactionAttributeSource 来做具体的解析工作,其父类 AbstractFallbackTransactionAttributeSource 定义了解析 TransactionAttribute 的优先级,核心方法是 computeTransactionAttribute() 。

AnnotationTransactionAttributeSource 默认只解析 public 修饰的方法,这也是导致 @Transactional 注解失效的一个原因,除此之外它还实现了父类中定义的两个模板方法:

同时为了支持 EJB 中定义的 javaxejbTransactionAttribute 和 JTA 中定义的 javaxtransactionTransactional 注解, AnnotationTransactionAttributeSource 选择将实际的提取工作代理给 TransactionAnnotationParser 。Spring 提供的 @Transactional 注解由 SpringTransactionAnnotationParser 进行解析。

SpringTransactionAnnotationParser 的源码还是很简单的,它使用 AnnotatedElementUtils 工具类定义的 find 语义来获取 @Transactional 注解信息。 RuleBasedTransactionAttribute 中 rollbackOn() 的实现还是挺有意思的,其它的都平平无奇。

RollbackRuleAttribute 是用来确定在发生特定类型的异常(或其子类)时是否应该回滚,而 NoRollbackRuleAttribute 继承自 RollbackRuleAttribute ,但表达的是相反的含义。 RollbackRuleAttribute 持有某个异常的名称,通过 getDepth(Throwable ex) 算法来计算指定的 Throwable 和持有的异常在继承链上的距离。

  程序猿只有在拿到需求以后才能开工, TransactionInterceptor 也一样,有了 TransactionAttributeSource 之后就可以有依据的增强了。观察类图, TransactionInterceptor 实现了 MethodInterceptor 接口,那么自然要实现接口中的方法:

可以看到, TransactionInterceptor 本身是没有实现任何逻辑的,它更像一个适配器。这样分层以后, TransactionAspectSupport 理论上就可以支持任意类型的 Advice 而不只是 MethodInterceptor 。实现上 TransactionAspectSupport 确实也考虑了这一点,我们马上就会看到。

invokeWithinTransaction() 的流程还是非常清晰的:

第一步前文已经分析过了,我们来看第二步。

TransactionInfo 是一个非常简单的类,我们就不费什么笔墨去分析它了。接着看第三步,这一步涉及到两个不同的 *** 作——提交或回滚。

至此, TransactionInterceptor 于我们而言已经没有任何秘密了。

  本篇我们一起分析了 spring-tx 是如何通过 spring-aop 的拦截器将普通方法增强为事务方法的,下篇就该说道说道 PlatformTransactionManager 抽象下的事务管理细节啦,我们下篇再见~~

1首先新建一个文件夹,如c:\\myWorkspace 2然后在myWorkspace中再新建一个文件夹,名为你的项目名 3如myProject,然后把你的源代码放到myProject中。 那么现在有文件目录如下 c:\myWorkspace\myProject\src c:\myWorkspace\myProject\bin

从AnnotationConfigApplicationContext切入分析源码,

AnnotationConfigApplicationContext的类图,其中继承了GenericApplicationContext,也继承了BeanDefinitionRegistry

分析这三个重要的方法

thisscanner = new ClassPathBeanDefinitionScanner(this);

实例化了扫面类,但是不是用这个类去扫面要加载的类,那这个类的作用是什么,是我们手动的扫面,看下面的例子

spring源码中会自动的扫描包下的类,比如标注了@Component @Configuration等注解的类,自动扫描的时候,会重新有从新new了一个ClassPathBeanDefinitionScanner(this);后续的文章会分析,那我们想手动的扫描呢,用的就是这个scanner

主要是读取配置类这里就是MyConfigurationclass,要注意的是只是将配置类加载到beanDefinitionMap中,不会去解析,通过refresh()方法解析的 ,并注入了很多的BeanFacrotyPostProcessor

thisreader = new AnnotatedBeanDefinitionReader(this);

AnnotationConfigUtilsregisterAnnotationConfigProcessors(thisregistry);

最终调用AnnotatedBeanDefinitionReader的有参构造器

registerAnnotationConfigProcessors方法

AnnotationConfigApplicationContext构造函数的register(componentClasses);

-->AnnotatedBeanDefinitionReader#register的thisreaderregister(componentClasses);

-->AnnotatedBeanDefinitionReader#doRegisterBean

就是最重要的refresh();方法,再后续的文章分析

以上就是关于Spring Tx源码解析(二)全部的内容,包括:Spring Tx源码解析(二)、spring4.2.4的源码在哪、spring源码分析等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9316028.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-27
下一篇2023-04-27

发表评论

登录后才能评论

评论列表(0条)

    保存