SpringBoot复习:(55)在service类中的方法上加上@Transactional注解后,Spring底层是怎么生成代理对象的?
SpringBoot run方法代码如下:

可以看到它会调用refreshContext方法来刷新Spring容器,这个refreshContext方法最终会调用AbstractApplicationContext的refresh方法,代码如下

如上图,refresh方法最终会调用finisheBeanFactoryInitialization方法,代码如下:


从上图可以看出,它最终会调用preInstantiateSingletons方法来实例化单例的bean,代码如下:


其中,每一个bean创建时都要调用getBean方法,getBean代码如下:

如上图,getBean调用doGetBean, doGetBean代码如下:




整体逻辑就是先从缓存中获取bean,如果为空则调用createBean来创建bean,createBean代码如下:


从上图看到,createBean调用了doCreateBean来完成bean创建,doCreateBean代码如下:


从上图可以看到doCreateBean调用了initializeBean来完成对bean的初始化,initializeBean代码如下:

从上图可以看到它调用了applyBeanPostProcessorsAfterInitialization,这个方法代码如下:

可以看到,applyBeanPostProcessorsAfterInitialization中获取了Spring容器中所有的BeanPostProcessor,然后调用它们的postProcessAfterInitialization方法来对bean进行后置处理,而可能的代理对象就是通过BeanPostProcessor生成的。而InfrastructureAdvisorAutoProxyCreator这个BeanPostProcessor就是来完成代理对象生成的(当然,前提是加了@Transactional注解,否则不会生成代理对象,会直接返回原始对象)

InfrastructureAdvisorAutoProxyCreator的postProcessAfterInitialization代码如下:

其中调用了wrapIfNecessary方法,wrapIfNecessary代码如下:

从上图我们看到,如果specificInterceptors不为空,则会去生成代理对象并返回,否则直接将原始对象返回。
getAdvicesAndAdvisorsForBean代码如下:

它调用了findEligibleAdvisors方法,代码如下:

findEligibleAdvisors首先从Spring容器中获取所有的Advisor,然后调用findAdvisorsThatCanApply来获取可以应用的Advisor,findAdvisorsThatCanApply代码如下:

它调用了AopUtils的静态方法findAdvisorsThatCanApply方法,代码如下:

其中调用的canApply方法代码如下:

其中调用的canApply代码如下:


其中调用的matches方法代码如下:

其中调用的getTransactionAttribute方法代码如下:


其中调用的computeTrasactionAttribute代码如下:


其中调用的findTransactionAttribute代码如下:

其中调用的determineTransactionAttribute代码如下:

其中会分别调用Spring容器中的TransactionAttributeParser进行注解分析,实际上只有一个SpringTransactionAttributeParser,SpringTransactionAttributeParser的parseTransactionAnnotation代码如下:

从上图可以看到,要从传入的元素(实际就是我们定义的业务方法)来获取它是否包含@Transactional注解,如果包含,则调用parseTransactionAnnotation来获取注解上配置的事务相关的属性(也就是在@Transactional注解上配置的那些值)

因此,最终决定是否生成代理对象的是parseTransactionAnnotation方法的返回值

一步一步往回返,最终返回到AbstractAutoProxyCreator的wrapIfNecessary方法:

如果parseTransactionAnnotation方法返回的是null,则这里的specificInterceptors为空,不会生成代理对象。
如果parseTransactionAnnotation方法返回的不是null,则这里的specificInterceptors大小为1,则会调用createProxy创建代理对象。
以上分析了是否要创建代理对象,开始分析代理对象的创建过程。createProxy代码如下:


可以看到,首先new出一个Proxy,然后设置targetSource(也就是bean的原始类型)和用于事务处理的Advisor,最有调用getProxy,getProxy代码如下:

其中调用的createAopProxy代码如下:

其中调用的createAopProxy代码如下:

默认情况下,SpringBoot会使用ObjenesisCglibAopProxy,如上图。ObjenesisCglibAopProxy的getProxy代码如下:


可以看到它最终会调用createProxyClassAndInstance方法来创建出代理对象,它的代码如下:

相关文章:
SpringBoot复习:(55)在service类中的方法上加上@Transactional注解后,Spring底层是怎么生成代理对象的?
SpringBoot run方法代码如下: 可以看到它会调用refreshContext方法来刷新Spring容器,这个refreshContext方法最终会调用AbstractApplicationContext的refresh方法,代码如下 如上图,refresh方法最终会调用finisheBeanFactoryInit…...
常用的图像校正方法
在数字图像处理中,常用的校正方法包括明场均匀性校正、查找表(LUT)校正和伽玛(Gamma)校正。这些校正方法分别针对不同的图像问题,可以改善图像质量,提升图像的可读性和可分析性。下面是这三种校…...
AWS security 培训笔记
云计算的好处 Amazon S3 (Storage) Amazon EC2 (Compute) 上图aws 的几个支柱:安全是其中一个啦 其中安全有几个方面 IAMdetection基础架构保护数据保护应急响应 关于云供应商的责任 data center 原来长这样 ,据说非常之隐蔽的 如果有天退役了…...
设计模式之代理模式(Proxy)的C++实现
1、代理模式的提出 在组件的开发过程中,有些对象由于某种原因(比如对象创建的开销很大,或者对象的一些操作需要做安全控制,或者需要进程外的访问等),会使Client使用者在操作这类对象时可能会存在问题&…...
vim 配置环境变量与 JDK 编译器异常
vim 配置环境变量 使用 vim 打开系统中的配置信息(不存在将会创建): vim ~/.bash_profile 以配置两个版本 JDK 为例(前提是已安装 JDK),使用上述命令打开配置信息: 输入法调成英文,输入 i&…...
TiDB v7.1.0 跨业务系统多租户解决方案
本文介绍了 TiDB 数据库的资源管控技术,并通过业务测试验证了效果。资源管控技术旨在解决多业务共用一个集群时的资源隔离和负载问题,通过资源组概念,可以限制不同业务的计算和 I/O 资源,实现资源隔离和优先级调度,提高…...
【题解】二叉树中和为某一值的路径(一)
二叉树中和为某一值的路径(一) 题目链接:二叉树中和为某一值的路径(一) 解题思路1:递归 我们或许想记录下每一条从根节点到叶子节点的路径,计算出该条路径的和,但此种思路用递归稍麻烦,我们可以试着把和转换为差&am…...
css中变量和使用变量和运算
变量: 语法:--css变量名:值; --view-theme: #1a99fb; css使用变量: 语法:属性名:var( --css变量名 ); color: var(--view-theme); css运算: 语法:属性名…...
数据结构之线性表的类型运用Linear Lists: 数组,栈,队列,链表
线性表 定义 一个最简单,最基本的数据结构。一个线性表由多个相同类型的元素穿在一次,并且每一个元素都一个前驱(前一个元素)和后继(后一个元素)。 线性表的类型 常见的类型:数组、栈、队列…...
成瘾机制中微生物群的神秘角色
谷禾健康 成瘾是一种大脑疾病,受害者无法控制地对某种物质或行为产生强烈的依赖和渴求,尽管这种行为会产生有害的后果。成瘾包括一系列物质滥用障碍,例如药物、酒精、香烟,过度饮食。近年来,吸毒成瘾急剧上升ÿ…...
arm安装docker与docker-copose
一、银河麒麟Arm64安装docker 1、docker 安装包地址: https://download.docker.com/linux/static/stable 2、解压,然后将docker目录下文件拷贝到/usr/bin里 tar -xf docker-18.09.3.tgz mv docker/* /usr/bin/ 3、准备 docker.service系统配置文件 &…...
9.文件基本操作
第四章 文件管理 9.文件基本操作 “打开文件和关闭文件”与平常鼠标双击打开文件和点击“X”关闭文件是有所不同的。 操作系统在处理open系统调用时主要做了以下两件事情,①根据我们提供的文件存放路径在外存当中找到这个目录对应的目录表&#x…...
【Java】Spring——Bean对象的作用域和生命周期
文章目录 前言一、引出Bean对象的作用域1.普通变量的作用域2.Bean对象的作用域 二、Bean对象的作用域1.Bean对象的6种作用域2.设置Bean对象的作用域 三、Bean对象的生命周期总结 前言 本人是一个普通程序猿!分享一点自己的见解,如果有错误的地方欢迎各位大佬莅临指导,如果你也…...
数字孪生助力智慧水务:科技创新赋能水资源保护
智慧水务中,数字孪生有着深远的作用,正引领着水资源管理和环境保护的创新变革。随着城市化和工业化的不断推进,水资源的可持续利用和管理愈发显得重要,而数字孪生技术为解决这一挑战提供了独特的解决方案。 数字孪生技术…...
css 实现文字横向循环滚动
实现效果 思路 ## 直接上代码,html部分 //我这里是用的uniapp <view class"weather_info_wrap"><view class"weather_info">当前多云,今晚8点转晴,明天有雨,温度32摄氏度。</view><view class&qu…...
VuePress 数学公式支持
前言 博主在为 VuePress1.0 博客添加数学公式支持过程中遇到如下问题 问题一 在配置诸如 markdown-it-texmath,markdown-it-katex,markdown-it-mathjax3 这些插件后遇到 Error: Dynamic require of "XXX" is not supported 问题二 配置插件 vuepress-plugin-ma…...
stm32控制蜂鸣器源代码(附带proteus线路图)
说明: 1 PB0输出0时,蜂鸣器发生; 2 蜂鸣器电阻值如果太大会导致电流太小,发不出声音; 3蜂鸣器额定电压需要设置得低一点,可以是2V,但不能高于3V,这更右上角的电阻值有关系&#x…...
selinux
一、selinux的说明 二、selinux的工作原理 三、selinux的启动、关闭与查看 Enforcing和permissive都是临时的,重启还是依据配置文件中,禁用selinux,修改配置文件: 之后重启生效 四、selinux对linux服务的影响...
使用opencv4.7.0部署yolov5
yolov5原理和部署原理就不说了,想了解的可以看看这篇部署原理文章 #include <fstream> #include <sstream> #include <iostream> #include <opencv2/dnn.hpp> #include <opencv2/imgproc.hpp> #include <opencv2/highgui.hpp>/…...
Python - 协程基本使用详解【demo】
一. 前言 协程(Coroutine)是一种轻量级的线程,也被称为用户级线程或绿色线程。它是一种用户态的上下文切换方式,比内核态的线程切换更为轻量级,能够高效的支持大量并发操作。 2. 使用协程的好处 Python 中的协程是通…...
3个创意突破:GitHub推荐项目精选的算法艺术与Canvas设计实践指南
3个创意突破:GitHub推荐项目精选的算法艺术与Canvas设计实践指南 【免费下载链接】skills 本仓库包含的技能展示了Claude技能系统的潜力。这些技能涵盖从创意应用到技术任务、再到企业工作流。 项目地址: https://gitcode.com/GitHub_Trending/skills3/skills …...
LFM2.5-1.2B-Thinking-GGUF一文详解:从模型结构到Web UI交互逻辑全链路解析
LFM2.5-1.2B-Thinking-GGUF一文详解:从模型结构到Web UI交互逻辑全链路解析 1. 模型概述与核心特点 LFM2.5-1.2B-Thinking-GGUF是Liquid AI推出的轻量级文本生成模型,专为低资源环境优化设计。该模型采用1.2B参数规模,在保持较高生成质量的…...
ai辅助开发:快马生成tailscale配置助手,并通过exposure功能实现团队共享
最近在团队协作开发时,遇到了一个很实际的问题:我们需要频繁配置Tailscale网络中的各种服务访问权限,但每次编写ACL规则都要反复查阅文档,效率很低。于是尝试用InsCode(快马)平台的AI能力,做了一个能自动生成配置建议的…...
AudioLDM-S异常处理:常见错误排查与解决方案
AudioLDM-S异常处理:常见错误排查与解决方案 1. 引言 AudioLDM-S作为一款强大的文本到音频生成工具,让用户只需输入简单的文字描述就能快速生成高质量的音效、音乐和语音。但在实际使用过程中,很多新手朋友经常会遇到各种问题,比…...
使用hcxtools与hashcat实现WiFi握手包的高效破解指南
1. 从零开始理解WiFi握手包破解原理 当你用手机连接家里的WiFi时,设备会与路由器进行四次"握手"确认身份。这个过程中交换的数据包就像保险箱的密码盘,虽然看不到具体密码,但记录了密码转动的轨迹。hcxtools和hashcat这对黄金搭档&…...
西门子S7-1200PLC与V90伺服通信实战:5步搞定SINA_POS功能块配置
西门子S7-1200PLC与V90伺服通信实战:5步搞定SINA_POS功能块配置 在工业自动化现场,PLC与伺服系统的协同工作已成为提升产线效率的核心环节。西门子S7-1200PLC搭配V90伺服驱动的组合,凭借其稳定性和灵活性,被广泛应用于包装机械、数…...
Cadence Virtuoso Calculator进阶技巧:代数模式与有效位数设置详解
Cadence Virtuoso Calculator进阶技巧:代数模式与有效位数设置详解 在集成电路设计的精密世界里,每一个参数的微小偏差都可能引发蝴蝶效应。作为Cadence Virtuoso平台的核心分析工具,Calculator的功能远不止于简单的数值运算——它实际上是连…...
这个Qt通讯组件库有点东西。咱们先从底层通讯开始盘——TCP、UDP、Serial三大件全齐活。拿UDP举个栗子,发送报文简单到像发短信
纯qt编写的通讯组件,包含tcp,udp,serial;plc客户端有mudbustcp,modbusrtu,finstcp,finsudp;plc服务端有modbustcp和modbusrtu。 实现其他的plc通信可集成原有基类,已封装…...
计算机毕业设计:基于爬虫与可视化的美食菜谱数据分析平台 Django框架 爬虫 机器学习 数据分析 可视化 食物 食品 菜谱(建议收藏)✅
博主介绍:✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌ > 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与…...
Anything V5效果展示:一键生成高质量二次元角色肖像图
Anything V5效果展示:一键生成高质量二次元角色肖像图 如果你对二次元文化感兴趣,或者想快速创作属于自己的动漫风格角色,那么今天要介绍的Anything V5绝对会让你眼前一亮。这是一个基于Stable Diffusion技术的高质量二次元图像生成模型&…...
