Spring-事务源码解析2

news2025/6/22 22:56:01

上一篇文章我们介绍了事务开启注解@EnableTransactionManagement源码解析《Spring-事务源码解析1》 里面提到了2个关键组件,这里我们分析下Spring如何利用这2个组件来给Bean创建代理对象。

文章待整理

先说下执行流程,当请求进来的时候,会执行JdkDynamicAopProxy的invoke方法,这时会拿到方法的拦截器链,下面是获取目标方法的拦截器链

List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

然后执行拦截器链中的最开始的拦截器,后面一次遍历,但是此时的拦截器就只有一个就是TransactionInterceptor事务方法拦截器

进到TransactionInterceptor就会执行TransactionInterceptor的invoke方法,下面看下invoke的流程

1、先拿到事务管理器的事务类型:PROPAGATION_REQUIRED,ISOLATION_DEFAULT;
2、在拿到事务的管理器也就是DataSourceTransactionManager

@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
      //目标类      
      Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
      //执行切面方法和目标方法
      return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
            @Override
            public Object proceedWithInvocation() throws Throwable {
                  return invocation.proceed();
            }
      });
}

protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation) throws Throwable {

      //1、事务隔离级别
      final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
      //2、事务管理器DataSourceTransactionManager
      final PlatformTransactionManager tm = determineTransactionManager(txAttr);


      //生成事务txInfo,里面包含本次事务状态,隔离级别,事务处理器,当本次事务执行完后需要关闭本次事务
      TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
      
      try {
      		//执行进入下一个链,此时只有一个也就是目标方法
            retVal = invocation.proceedWithInvocation();
      }
      catch (Throwable ex) {
            //更改txInfo里面的状态
            completeTransactionAfterThrowing(txInfo, ex);
            throw ex;
      }
      finally {
            cleanupTransactionInfo(txInfo);
      }
      commitTransactionAfterReturning(txInfo);//根据状态是否commit
      return retVal;
}

五、疑问

1、带有@Transaction注解的Bean实例化的时候,怎么如果判断该Bean带有@Transaction方法

1、InfrastructureAdvisorAutoProxyCreator#postProcessAfterInitialization
—>2、BeanFactoryTransactionAttributeSourceAdvisor
—>3、AnnotationTransactionAttributeSource
—>4、SpringTransactionAnnotationParser判断@Transaction

最终通过SpringTransactionAnnotationParser来判断Bean的方法是否带有@Transaction注解

拓展:
InfrastructureAdvisorAutoProxyCreator里面有个advisedBeans属性,在Bean的创建过程会判断Bean里面 是否是带有事务注解@Transaction的方法,如果有就会被加到advisedBeans里面去。

private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<Object, Boolean>(256);

注意:
1、BeanFactoryTransactionAttributeSourceAdvisor事务增强器在advisedBeans是false的形式存在
2、transactionInterceptor也是false

2、带有@Transaction注解的代理Bean在哪个流程被创建

在执行BeanPostProcess处理器链的时候,由InfrastructureAdvisorAutoProxyCreator#postProcessAfterInitialization方法执行创建,该方法会调用wrapIfNecessary方法完成代理创建

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	  .......
      //这里是拿到BeanFactoryTransactionAttributeSourceAdvisor也就是“事务增强器”
      Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
      if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);//key就是带有@Transaction的BeanName
            Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            return proxy;//返回代理对象
      }
      return bean;
}

3、如何创建@Transaction注解的Bean
默认是使用JDK动态代理

1、先创建ProxyFactory对象,设置属性
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTargetSource(目标对象LLServcieImpl);
proxyFactory.setInterfaces(目标接口LLServcie);
proxyFactory.addAdvisor(事务增强器BeanFactoryTransactionAttributeSourceAdvisor);
proxyFactory.getProxy(getProxyClassLoader())//调用下面的代码
//2、生成动态代理对象
proxiedInterfaces=AopProxyUtils.completeProxiedInterfaces(事务增强器, true);
//设置代理对象要实现接口和InvocationHandler对象
Proxy.newProxyInstance(classLoader, proxiedInterfaces, JdkDynamicAopProxy);

其中proxiedInterfaces包含接口

0 = {Class@3511} “interface cn.tedu.sample2.util.LLServcie”
1 = {Class@3676} “interface org.springframework.aop.SpringProxy”
2 = {Class@5780} “interface org.springframework.aop.framework.Advised”
3 = {Class@3897} “interface org.springframework.core.DecoratingProxy”

4、InfrastructureAdvisorAutoProxyCreator类的作用

1、postProcessBeforeInstantiation方法主要是针对所有要创建的Bean,判断存到advisedBeans里面是false还是true
2、postProcessAfterInitialization方法,处理带有@Transcation的Bean,创建代理Bean

六、总结

1、先通过@EnableTransactionManagement引入TransactionManagementConfigurationSelector
2、通过TransactionManagementConfigurationSelector,导入AutoProxyRegistrar,ProxyTransactionManagementConfiguration
3、AutoProxyRegistrar会向容器中注册InfrastructureAdvisorAutoProxyCreator
4、ProxyTransactionManagementConfiguration会向容器定义三个Bean:事务增强器、@Transaction注解解析器、事务方法拦截器
5、执行Bean的后置处理器时,通过InfrastructureAdvisorAutoProxyCreator的postProcessAfterInitialization方法创建代理对象
6、创建代理对象时,通过事务增强器BeanFactoryTransactionAttributeSourceAdvisor来得到代理类要实现的接口SpringProxy、Advised、DecoratingProxy,最终生成代理对象

7、当请求进来时,先进入JdkDynamicAopProxy的invoke方法
8、invoke里面会调用TransactionInterceptor的invoke方法,里面会调用invokeWithinTransaction方法
9、invokeWithinTransaction里面会在调用目标方法前开启事务,catch失败设置状态,然后finally根据状态来确认是否commit

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1086381.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TensorFlow入门(二十五、单个神经元的扩展——Maxout网络)

Maxout网络的原理 Maxout是Goodfellow在2013年提出的一个新的激活函数,与其它的激活函数相比,Maxout是需要参数的,且参数可以通过网络的反向传播得到学习,因此它比其它激活函数有着更好的性能,理论上可以拟合任意凸函数,进而使得网络取得更好的性能。 Maxout网络主要是扩展单个…

移动app广告变现,对接广告联盟还是选择第三方聚合广告平台?

作为互联网广告的载体&#xff0c;APP天生就比线下传统广告位更具优势&#xff0c;不受地域限制可以辐射到地球上的每一个角落&#xff0c;可以让广告获得更广的覆盖面。通过丰富的广告形式&#xff0c;精准的目标用户画像&#xff0c;也可以更好地实现品牌广告或效果广告的投放…

主流大模型训练库和框架的介绍

文章目录 前言1.主流大模型框架介绍 前言 参考&#xff1a; Pytorch训练模型损失Loss为Nan或者无穷大&#xff08;INF&#xff09;原因 1.主流大模型框架介绍

模拟电路基础知识经典 200问,收藏这些就够了!

大家总说模电知识总是学不会&#xff0c;IC修真院为大家整理了模电经典200问&#xff0c;看看你掌握了多少&#xff0c;文末可以获取全部哦。 文末可领全部文档 1、半导体材料制作电子器件与传统的真空电子器件相比有什么特点? 答&#xff1a;频率特性好、体积小、功耗小&…

CDN加速服务:网站快递服务

原始服务器&#xff1a;网站的储藏库 想象一下&#xff0c;CDN加速服务的旅程从原始服务器开始&#xff0c;这个服务器就像是一个巨大的储藏库&#xff0c;通常藏身于数据中心或云服务提供商的服务器中。这里存放着网页、图片、视频、应用程序等静态和动态的货品。 CDN节点&…

SpringBoot整合JWT、实现登录和拦截

SpringBoot整合JWT 、实现登录和拦截 一、JWT简介1.什么是JWT2.为什么要用JWT3.传统Session认证的弊端4.JWT认证的优势5.JWT结构 二、SpringBoot整合JWT1.引入依赖2.JWT工具类3.自定义拦截器4.异常处理1.自定义异常ServiceException2.全局异常处理器3.同一封装返回结果 3.登录实…

Window10运行onnxruntime报错的处理

背景 在Windows10中安装好英伟达驱动、cuda、cudnn等资源&#xff0c;然后运行程序的时候&#xff0c;发现程序会在加载模型时崩溃。 经过一番查找后&#xff0c;得到输出的信息是说是缺少zlibwapi.dll。 这个问题是去年做的一个项目时发现的&#xff0c;忘记当时是怎么发现了…

Java标识符和关键字,Java常量的定义和分类

任何一种计算机语言都离不开标识符和关键字&#xff0c;因此下面将详细介绍 java 的标识符、关键字和保留字。 标识符 Java 中标识符是为方法、变量或其他用户定义项所定义的名称。标识符可以有一个或多个字符。在 Java 语言中&#xff0c;标识符的构成规则如下。 标识符由数…

Go的运算符解密:探索计算的奥秘

目录 算术运算符 赋值运算符 比较运算符 逻辑运算符 位运算符 其他运算符 运算符优先级 代码示例 更多关于Go的相关技术点&#xff0c;敬请关注公众号&#xff1a;CTO Plus后续的发文&#xff0c;有问题欢迎后台留言交流。 原文&#xff1a;Go的运算符解密&#xff1a;…

论文阅读之【Is GPT-4 a Good Data Analyst?(GPT-4是否是一位好的数据分析师)】

文章目录 论文阅读之【Is GPT-4 a Good Data Analyst?&#xff08;GPT-4是否是一位好的数据分析师&#xff09;】背景&#xff1a;数据分析师工作范围基于GPT-4的端到端数据分析框架将GPT-4作为数据分析师的框架的流程图 实验分析评估指标表1&#xff1a;GPT-4性能表现表2&…

日语学习网站web项目

支持日语五十音,平片假名、罗马音、词义转换、百度翻译功能,方便日语初学者学习日语发音 介绍 采用vitevue3ts技术栈开发, pinia管理全局化。主要是为了日语入门学习五十音, 以及日语句子罗马 发音对照练习。 参考以下两个项目完成 https://github.com/hexenq/kuroshiro ht…

SpringMVC的请求处理

请求映射路径的配置 请求映射路径的配置主要是通过RequestMapping注解实现的 相关注解作用使用位置RequestMapping设置控制器方法访问路径的资源&#xff0c;可以接收任何请求方法和类上GetMapping设置控制器方法访问路径的资源&#xff0c;可接收GET请求方法和类上PostMappin…

绿源正式登陆港股,行业老将凭原创科技走向新未来

两轮电动车领域历史最悠久的老将之一——绿源&#xff0c;正式掀开发展之路的新篇章。10月12日&#xff0c;绿源正式登陆港交所&#xff0c;上市首日股价开盘向上&#xff0c;涨幅一度超过9%。 此前&#xff0c;绿源的招股书失效以及在地方抽检中出现的负面新闻&#xff0c;引…

YOLOv7改进策略:RIFormerBlock助力检测|CVPR2023 RIFormer:无需TokenMixer也能达成SOTA性能的极简ViT架构

💡💡💡本文属于原创独家改进: 稀疏重参数RIFormerBlock模型引入YOLOv7进行创新性 RIFormerBlock | 亲测在多个数据集实现涨点; 收录: YOLOv7高阶自研专栏介绍: http://t.csdnimg.cn/tYI0c ✨✨✨前沿最新计算机顶会复现 🚀🚀🚀YOLOv7自研创新结合,轻松…

微信支付(小程序)

1、配置回调地址 2、小程序和微信支付进行绑定 3、小程序支付需要获取openId 4、uniapp中支付的关键代码 uni.requestPayment({"provider": "wxpay", "orderInfo": {"appid": "wx499********7c70e", // 微信开放平台 - 应…

如何给视频加上酷炫边框?简单几步搞定

随着社交媒体的普及&#xff0c;越来越多的人开始关注如何给自己的视频加上炫的边框&#xff0c;以增加观赏性和吸引力。而乔拓云作为一款在线海报制作工具&#xff0c;为这一需求提供了便捷的解决方案。下面就让我们一起来看看如何通过乔拓云给视频加上酷炫边框吧&#xff01;…

HPE设备固件升级步骤

一.打开HPE的support官网 https://support.hpe.com/connect 二.搜索需要的设备型号 三.搜索需要的固件 四.选择需要安装的版本及环境 5.下载与安装&#xff0c;也可以查看历史版本

“上海设计100+”和“设享奖EDW”先后揭晓,深兰科技皆获大奖

国庆前夕&#xff0c;“上海设计100”和“设享奖EDW”两项产品设计大奖的获奖榜单先后揭晓&#xff0c;深兰科技出品的计算机视觉工业检测标准化设备-剑齿虎在两项大奖的评选中皆获大奖。 01上海设计100——2023世界设计之都大会 9月26日&#xff0c;由上海市人民政府主办&…

Latex写作如何划钩与打叉

文章目录 概要实现在这里插入代码片效果 概要 我们经常在论文写作中需要划钩 “√” 与打叉 “”&#xff0c;本文介绍在latex中的几种实现方式。 实现在这里插入代码片 \documentclass{article} \usepackage{bbding} %重要&#xff1a;首先在导言区调用bbding包\begin{docu…

PCB射频天线设计基本要点及布局技巧

射频天线设计与布局是需要认真关注细节的领域之一&#xff0c;也是混合信号设计师给出的一些提示。如果刚开始接触高频模拟设计&#xff0c;可采用本文给出的这些技巧&#xff0c;以确保RF设计具有良好的隔离效果和信号完整性。 如今&#xff0c;人们已很难想到哪个消费产品不含…