从根儿上学习spring 十一 之run方法启动第四段(5)

news2024/10/2 6:39:51

图15-AbstractAutowireCapableBeanFactory#doCreateBean方法

我们接着讲doCreateBean方法,之前对循环依赖做了些解释,我们接着往下看populateBean(beanName, mbd, instanceWrapper)方法

图15-572行

这行就是调用populateBean(beanName, mbd, instanceWrapper)方法对实例化好的bean对象进行属性注入,也就是处理我们经常使用的@autowired或者@resource这些注解。我们看下该方法的代码

图16-AbstractAutowireCapableBeanFactory#populateBean方法

图16-1277到1286行

这几行没什么好说的,做了个简单的空值校验,如果bean实例为空但beanDefinition却定义了bean属性的value值则报错,否则直接返回。

图16-1291到1303行

这几行的目的只有一个,就是调用后置处理器InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation方法对bean属性进行设值。如果该方法返回了false说明bean属性已设置完毕不需要populateBean方法后续继续对bean进行属性设置。continueWithPropertyPopulation属性就是来判断是否需要后续继续对bean的属性进行设置。对于具体有哪些后置处理器做了什么不是我们当前的重点,大家只需要知道这里spring为我们提供了一个扩展点即可。这个后置处理器我们前面也说过,这里就不赘述了。

图17-AbstractAutowireCapableBeanFactory#populateBean方法

图17-1309到1322行

这几行的功能主要是获取bean实例中的属性,然后根据beanDefinition定义的注入类型判断是否根据name注入或者根据类型注入去获取每个属性对应的bean实例。根据name注入也就是通过beanName去spring容器获取该属性的bean实例,根据类型注入是根据属性class类型到spring容器中获取该属性的bean实例。最后将获取到的属性bean实例根据属性名作为key放到newPvs变量中,为后面对属性设值做准备。

图18-AbstractAutowireCapableBeanFactory#populateBean方法

图18这段逻辑主要做了两件事,

1331-1342:判断当前spring容器是否有InstantiationAwareBeanPostProcessor后置处理器的存在,如果有则执行其postProcessPropertyValues方法,该方法允许我们在对bean设置属性前对属性的值进行修改,也就是修改pvs或者直接替换pvs;

1343-1345:对bean的属性进行检查,检查必填属性是否为空。一共有4中检查模式都定义在AbstractBeanDefinition类里,分别是DEPENDENCY_CHECK_NONE-不检查,DEPENDENCY_CHECK_OBJECTS-检查引用类型的属性,DEPENDENCY_CHECK_SIMPLE-检查基本类型的属性,DEPENDENCY_CHECK_ALL-所有类型的属性都检查。

1348-1350:通过反射对属性进行设值,完成属性注入。

讲到这AbstractAutowireCapableBeanFactory#populateBean方法也就讲完了,接下来我们开始讲图15-AbstractAutowireCapableBeanFactory#doCreateBean方法的initializeBean(beanName, exposedObject, mbd)方法。

图16-AbstractAutowireCapableBeanFactory#initializeBean(Object, RootBeanDefinition)方法

AbstractAutowireCapableBeanFactory#initializeBean(Object, RootBeanDefinition)方法的逻辑相对而言简单了很多,我们从上往下看来捋一下。

图16-1674到1682行

这几行的逻辑就是调用了invokeAwareMethods(beanName, bean)方法,这个方法的逻辑很简单就是判断当前初始化的bean是不是实现了Aware接口,如果实现了该接口那么就判断具体的Aware接口类型,比如是否是BeanNameAware接口,是的话则调用其setBeanName方法等等,这个方法很简单大家自己点进去看下就明白了,我就不赘述了。

图16-1684到1687行

这几行就是调用之前我们说过的一个bean后置处理BeanPostProcessor的postProcessBeforeInitialization方法,该方法的含义是在执行bean的初始化前执行,具体指的是在执行spring的InitializingBean#afterPropertiesSet方法前执行,这个方法我们马上就会说到。

图16-1690行

这行就是判断当前bean是否实现了InitializingBean接口,如果实现了这个接口则调用其afterPropertiesSet方法,这也是spring提供的给我们的扩展,给我们提供自定义初始化bean的能力。

图16-1697到1699行

这几行是调用BeanPostProcessor的postProcessAfterInitialization方法,在bean初始化完成之后提供的一个扩展方法。到这我们的bean就彻底初始化完毕了。

让我们再回到AbstractAutowireCapableBeanFactory#doCreateBean方法的剩余部分。

图17-AbstractAutowireCapableBeanFactory#doCreateBean方法

earlySingletonExposure变量我们之前说过,如果spring容器允许单例循环依赖且当前bean是单例且当前bean正在创建改变量就为true。然后调用getSingleton(beanName, false)方法第二个参数为false表示不允许从单例工厂中获取实例,只能从单例容器singletonObjects或者提前暴露的单例容器earlySingletonObjects中获取实例。

目前虽然bean已经初始化好但目前spring还未将bean实例放入单例容器singletonObjects中,所以在没有出现循环依赖的情况下这里获取到的Object earlySingletonReference变量为空没啥好说的。如果earlySingletonReference不为空说明出现了循环依赖,当前beanName对应的bean提前暴露了一个实例就是earlySingletonReference。

接下来判断exposedObject == bean,这个判断一般都是相对的,因为如果是循环依赖的情况且bean是需要动态代理的,那么在前面getEarlyBeanReference(beanName, mbd, bean)方法执行的时候就会执行动态代理,后面就不会再执行动态代理,这也是为什么这个判断成立的情况下要使用earlySingletonReference给exposedObject赋值的原因。

如果exposedObject不等于bean,说明在initializeBean方法里执行后置处理器时更改了bean的引用,那么提前暴露出去的bean也将失效。这时候如果提前暴露的bean已经被其它bean引用了,那就需要报错。

最后判断当前bean是否需要注册为DisposableBean,注册为DisposableBean的话在容器销毁时会执行其destroy()方法。

感谢大家的观看,希望这些文章可以帮助大家更好理解spring。

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

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

相关文章

目标检测——YOLOv10: Real-Time End-to-End Object Detection

YOLOv10是在YOLOv8的基础上,借鉴了RT-DETR的一些创新点改进出来的 标题:YOLOv10: Real-Time End-to-End Object Detection论文:https://arxiv.org/pdf/2405.14458源码:https://github.com/THU-MIG/yolov10 1. 论文介绍 在过去的几…

【C语言】详解feof函数和ferror函数

文章目录 前言1. feof1.1 feof函数原型1.2 正确利用函数特性读写文件1.2.1 针对文本文件1.2.2 针对二进制文件 1.3 feof函数的原理1.4 feof函数实例演示 2. ferror2.1 ferror函数原型 前言 或许我们曾在网络上看过有关于feof函数,都说这个函数是检查文件是否已经读…

Windows系统使用内网穿透配置Mysql公网地址实现IDEA远程连接

文章目录 前言1. 本地连接测试2. Windows安装Cpolar3. 配置Mysql公网地址4. IDEA远程连接Mysql5. 固定连接公网地址6. 固定地址连接测试 前言 IDEA作为Java开发最主力的工具,在开发过程中需要经常用到数据库,如Mysql数据库,但是在IDEA中只能…

【Python学习手册(第四版)】学习笔记15-文档(注释、PyDoc等)

个人总结难免疏漏,请多包涵。更多内容请查看原文。本文以及学习笔记系列仅用于个人学习、研究交流。 本文主要介绍程序的文档概念。包括为程序编写的注释,以及内置工具的文档。讲解文档字符串、Python的在线手册等资源、以及PyDoc的help函数和网页接口。…

蒙电通无人机航线规划系统 雷达点云电力应用软件

蒙电通无人机航线规划系统,它可进行标记杆塔、切档、自动对点云数据分类和点云抽稀等处理,按3张或6张照片自动生成航线,或按自定义航线模型生成航线,支持安全性检测。在满足当地巡检标准的前提下,系统操作非常简便。 …

llama神经网络的结构,llama-3-8b.layers=32 llama-3-70b.layers=80; 2000汉字举例说明

目录 llama-3-8b.layers=32 llama-3-70b.layers=80 llama神经网络的结构 Llama神经网络结构示例 示例中的输入输出大小 实际举例说明2000个汉字文本数据集 初始化词嵌入矩阵 1. 输入层 2. 嵌入层 3. 卷积层 4. 全连接层 llama-3-8b.layers=32 llama-3-70b.laye…

跑深度学习模型Ⅲ:正确安装与torch版本对应的其他torch包

pytorch的正确安装可以回看我前面的博客跑深度学习模型Ⅱ:一文安装正确pytorch及dgl-CSDN博客 这篇博客将安装torch_grometric,torch_scatter, torch_sparse, torch_cluster库 1. 查看自己的torch版本 进入cmd 切换到要用的python环境中,输…

ADB Installer 0 file(s)copied

在为泡面神器刷安卓,做准备工作装ADB时报错了,以下是报错提示 再用cmd命令adb version验证下,提示adb不是有效命令,百分百安装失败了,往上各种搜索查询均没有对症的,其中也尝试了安装更新版本的&#xff0c…

2024版本IDEA创建Servlet模板

IDEA 版本 2024.1.4 新版本的 IDEA 需要自己创建 Servlet 模板 旧版本 IDEA 看我这篇文章:解决IDEA的Web项目右键无法创建Servlet问题_2024idea无法创建servlet项目-CSDN博客文章浏览阅读216次,点赞7次,收藏3次。解决IDEA的Web项目右键无法创…

AGI思考探究的意义、价值与乐趣 Ⅴ

搞清楚模型对知识或模式的学习与迁移对于泛化意味什么,或者说两者间的本质?相信大家对泛化性作为大语言模型LLM的突出能力已经非常了解了 - 这也是当前LLM体现出令人惊叹的通用与涌现能力的基础前提,这里不再过多赘述,但仍希望大家…

【Python学习手册(第四版)】学习笔记14-迭代器和列表解析(一)

个人总结难免疏漏,请多包涵。更多内容请查看原文。本文以及学习笔记系列仅用于个人学习、研究交流。 本文主要以通俗易懂的语言介绍迭代器(文件迭代、手动迭代iter和next等),列表解析式包括基础知识包括写法、文件上使用列表解析…

繁简之争:为什么手机芯片都是 ARM

RISC 和 CISC 指令集 之前的文章《揭秘 CPU 是如何执行计算机指令的》中说到,如果从软件的角度来讲,CPU 就是一个执行各种计算机指令(Instruction Code)的逻辑机器。 计算机指令集是计算机指令的集合,包括各种类型的…

Redis进阶(四):哨兵

为了解决主节点故障,需要人工操作切换主从的情况;因此需要一种方法可以自动化的切换:哨兵的引入大大改变这种情况。 哨兵的基本概念 自动切换主从节点 哨兵架构 1、当一个哨兵节点发现主节点挂了的时候,还需要其他节点也去检测一…

Cyber Weekly #18

赛博新闻 1、Google 狂卷小模型,2B 参数 Gemma 2 赶超 GPT-3.5 Google本周发布了开源的轻量级、高性能模型 Gemma 2 2B。它拥有 20 亿参数,是从更大规模的模型中提炼而来的,在 LMSYS 大模型竞技场的得分超越了 GPT-3.5 和 Mixtral 8x7B。该…

【12.PIE-Engine案例——加载Landsat 7 SR单景影像】

原始路径 欢迎大家登录航天宏图官网查看本案例原始来源 最后结果 具体代码 /*** File : Landsat7SRImage* Time : 2020/7/21* Author : piesat* Version : 1.0* Contact : 400-890-0662* License : (C)Copyright 航天宏图信息技术股份有限公司* Desc …

429总线协议

传输方式 单向方式:信息只能从通信设备的发送口输出,经传输总线传至与它相连的需要该信息的其他设备的接口。在两个通信设备间需要双向传输时,则每个方向上各用一个独立的传输总线。 编码方式 信号从高电平回归零电平表示逻辑状态1&#x…

卡码网--数组篇(移除元素)

系列文章目录 文章目录 系列文章目录前言27. 移除元素总结 前言 代码随想录:详情链接 27. 移除元素 力扣27 https://leetcode.cn/problems/remove-element/description/ Step1: 读题: 原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的…

MySQL基础练习题22-第二高的薪水

目录 题目 准备数据 分析数据 题目 查询并返回 Employee 表中第二高的薪水 。如果不存在第二高的薪水,查询应该返回 null(Pandas 则返回 None) 。 准备数据 ## 创建库 create database db; use db;## 创建表 Create table If Not Exists Employee (id int, sa…

JavaDS —— AVL树

前言 本文章将介绍 AVL 树的概念,重点介绍AVL 树的插入代码是如何实现的,如果大家对 AVL 树的删除(还是和二叉搜索树一样使用的是替换删除法,然后需要判断是否进行旋转调整)感兴趣的话,可以自行去翻阅其他…

WaitGroup

第一节:WaitGroup 概述 1. WaitGroup 简介 WaitGroup 是 Go 语言标准库 sync 包中的一个并发同步工具,它用于协调主 goroutine 与多个工作 goroutine 的执行。通过计数器跟踪还未完成的工作 goroutine 的数量,WaitGroup 能够确保主 goroutin…