spring部分源码分析及Bean的生命周期理解

前言:

本文整体框架是通过refresh方法这个入口进入分析:分析IOC容器的创建及一些Bean的生命周期的知识点,写得确实一般般,感觉自己的有些前置知识并没有理解的很到位,所以,这篇文件先记录一下,等以后理解得好了再来更新。


整体的流程:

 

 我们先将bean的配置信息写在配置文件中,再通过ClassPathXmlApplicationContext类读取,并管理。

这个图中的入口还有一个概念:

beandefinition:在Spring框架中,BeanDefinition是描述和定义Spring容器中的Bean的元数据对象。它包含了定义Bean的相关信息,例如Bean的类名、作用域、生命周期等。

接着我们打断点进入:

 

1: this.prepareRefresh()

这个方法就是定义spring容器的一些基本信息

该方法会主要做准备操作,设置初始化的数据和当任何属性资源激活后设置活动的标记。还会保存一些监听器。

2:this.obtainFreshBeanFactory()

refreshBeanFactor:创建了一个新的BeanFactory:ConfigurableListableBeanFactory

 

这里的this.loadBeanDefinitions(beanFactory)就会从配置文件中加载容器的信息。

3:this.prepareBeanFactory(beanFactory);

创建BeanFactory之后,还需要对这个BeanFactory进行一个准备工作:

例如:类加载器和后置处理器

4:this.postProcessBeanFactory(beanFactory);

我们点进去之后发现这个方法啥都没有,

这是一个空接口,允许开发人员往这个接口中加入自定义逻辑。

不同的spring容器也可以做不同的操作。

5:this.invokeBeanFactoryPostProcessors(beanFactory)

这个方法我们顾名思义调用BeanFactory的后处理器的方法,但是这个时候并不会创建Bean对象

 我们看这段源码之前,我们还涉及到了两个接口:

  • BeanFactoryPostProcessor:允许你修改现有 Bean 的定义,但不能注册新的 Bean 定义。
  • BeanDefinitionRegistryPostProcessor:允许你修改 Bean 定义和注册新的 Bean 定义,它是更高级的,通常在更早的阶段执行。

我们点进来看看。 

这段源码的逻辑比较复杂,总结下来说就是invokeBeanFactoryPostProcessors() 方法的确是用来处理 BeanFactory 的配置和注册后处理器的

 6:this.registerBeanPostProcessors(beanFactory):

这也是在注册后处理器,不过这个是专门的关于Bean生命周期的后处理器

简单理解下来就是:这个方法注册的后处理器更多,而且是与 Bean 生命周期相关的后处理器

并且这个方法也会根据不同的IOC容器进行一个注册。

7:this.initMessageSource(); this.initApplicationEventMulticaster();

国际化,applicationContext默认是支持国际化的,因为他继承了MessageSource接口所以能够实现国际化,这里不进行说明了,如有兴趣可以查询该链接


在Spring容器中初始化事件广播器,事件广播器用于事件的发布。

程序首先会检查bean工厂中是否有bean的名字和这个常量(applicationEventMulticaster)相同的,如果没有则说明没有那么就使用默认的ApplicationEventMulticaster 的实现:SimpleApplicationEventMulticaster

8: onRefresh():

点进去:

这也是一个空方法,也是留着给后面进行扩展

我们也可以感觉到,像spring这种牛逼的框架,留的扩展点也真的是不少。

9:this.registerListeners()

 注册应用的监听器。

在 Spring 框架中,registerListeners() 方法主要用于注册应用上下文(ApplicationContext)中的事件监听器。它是一个重要的机制,通过此机制,Spring 可以实现事件驱动的编程模型

这一个监听器的理解,我觉得我理解并不好,问了GPT,也不明白什么意思,这里留一个

TODO

如果以后有机会会回来补充的。 

10:this.finishBeanFactoryInitialization(beanFactory);

finishBeanFactoryInitialization 是 Spring 框架中一个关键的方法,用于完成 BeanFactory 的初始化过程它确保所有的 Bean 都已正确初始化并且容器处于可用状态

这个方法也涉及到Bean的生命周期。

Bean的生命周期:

流程图:

代码演示:

1:定义一个普通类:
public class BeanTest implements BeanNameAware, InitializingBean , DisposableBean {private String name;public BeanTest() {System.out.println("实例化");}public String getName() {return name;}public void setName(String name) {System.out.println("依赖注入");this.name = name;}public void init(){System.out.println("初始化");}public void destory(){System.out.println("销毁");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("InitializingBean方法执行");}@Overridepublic void setBeanName(String name) {System.out.println("BeanNameAware方法执行");}@Overridepublic void destroy() throws Exception {System.out.println("DisposableBean方法执行");}
}
2:配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="a" class="com.javassmprojects.bean3.BeanTest" init-method="init" destroy-method="destory"><property name="name" value="BeanTest"></property></bean><bean id="MyProcessor" class="com.javassmprojects.bean3.MyPostProcess"></bean>
</beans>
3:MyPostProcessor:
public class MyPostProcess implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if("a".equals(beanName)){System.out.println(beanName+"我是后处理器的before方法");}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if("a".equals(beanName)) {System.out.println(beanName + "我是后处理器的after方法");}return bean;}
}
4:创建测试类测试:
class BeanTestTest {@Testpublic void test01(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beantest.xml");applicationContext.getBean("a");System.out.println("使用Bean对象");((ClassPathXmlApplicationContext)applicationContext).close();}}

测试结果:

实例化
依赖注入
BeanNameAware方法执行
a我是后处理器的before方法
InitializingBean方法执行
初始化
a我是后处理器的after方法
使用Bean对象
15:13:48.503 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext -- Closing org.springframework.context.support.ClassPathXmlApplicationContext@4fb0f2b9, started on Tue Jul 23 15:13:48 CST 2024
DisposableBean方法执行
销毁

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MAT使用

概念 Shallow heap & Retained Heap Shallow Heap就是对象本身占用内存的大小。 Retained Heap就是当前对象被GC后&#xff0c;从Heap上总共能释放掉的内存(表示如果一个对象被释放掉&#xff0c;那会因为该对象的释放而减少引用进而被释放的所有的对象&#xff08;包括…

CentOS 8中 更新或下载时报错:为仓库 ‘appstream‘ 下载元数据失败 : Cannot prepare internal mirrorlist

一、错误重现 CentOS Stream 8 - AppStream 0.0 B/s | 0 B 00:00 Errors during downloading metadata for repository appstream: - Curl error (6): Couldnt resolve host name for http://mirrorlis…

docker tomcat 404

HTTP 404状态码表示“Not Found”&#xff0c;即服务器无法找到请求的页面。 当用户尝试访问一个不存在的网页时&#xff0c;服务器会返回这个状态码。这个状态码是HTTP协议的一部分&#xff0c;用于告知客户端&#xff08;通常是浏览器&#xff09;服务器无法完成请求。404状…

设计模式13-单件模式

设计模式13-单件模式 写在前面对象性能模式典型模式1. 单例模式&#xff08;Singleton Pattern&#xff09;2. 享元模式&#xff08;Flyweight Pattern&#xff09;3. 原型模式&#xff08;Prototype Pattern&#xff09;4. 对象池模式&#xff08;Object Pool Pattern&#xf…

软件测试最全面试题及答案整理(2024最新版)

目录 1、你的测试职业发展是什么? 2、你认为测试人员需要具备哪些素质 3、你为什么能够做测试这一行 4、测试的目的是什么? 5、测试分为哪几个阶段? 6、单元测试的测试对象、目的、测试依据、测试方法? 7、怎样看待加班问题 8、结合你以前的学习和工作经验&#xf…

34_YOLOv5网络详解

1.1 简介 YOLOV5是YOLO&#xff08;You Only Look Once&#xff09;系列目标检测模型的一个重要版本&#xff0c;由 Ultralytics 公司的Glenn Jocher开发并维护。YOLO系列以其快速、准确的目标检测能力而闻名&#xff0c;尤其适合实时应用。YOLOV5在保持高效的同时&#xff0c…

ForCloud全栈安全体验,一站式云安全托管试用 开启全能高效攻防

对于正处于业务快速发展阶段的企业&#xff0c;特别是大型央国企而言&#xff0c;日常的安全部署和运营管理往往横跨多家子公司&#xff0c;所面临的挑战不言而喻。尤其是在面对当前常态化的大型攻防演练任务时&#xff0c;难度更是呈“几何级数”上升&#xff1a; 合规难 众…

Linux中进程的控制

一、进程的创建 1、知识储备 进程的创建要调用系统接口&#xff0c;头文件 #include<unistd.h> 函数fork() 由于之前的铺垫我们现在可以更新一个概念 进程 内核数据结构&#xff08;task_struct, mm_struct, 页表....&#xff09; 代码 数据 所以如何理解进程的独…

最新 Docker 下载镜像超时解决方案:Docker proxy

现在Docker换源也下载失败太常见了&#xff0c;至于原因&#xff0c;大家懂得都懂。本文提供一种简洁的方案&#xff0c; 利用 Docker 的http-proxy&#xff0c;代理至本机的 proxy。 文章目录 前言Docker proxy 前言 这里默认你会安装 clash&#xff0c;然后有配置和数据库。…

华为云.云日志服务LTS及其基本使用

云计算 云日志服务LTS及其基本使用 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28550…

开机出现grub无法进入系统_电脑开机出现grub解决方法

最近有小伙伴问我电脑开机出现grub无法进入系统怎么回事&#xff1f;电脑开机出grub的情况有很多&#xff0c;电脑上安装了Linux和Win10双系统&#xff0c;但是由于格式化删除了Linux之后&#xff0c;结果win10开机了之后&#xff0c;直接显示grub&#xff1e;&#xff0c;无法…

平面五杆机构运动学仿真matlab simulink

1、内容简介 略 89-可以交流、咨询、答疑 2、内容说明 略 ] 以 MATLAB 程序设计语言为平台 , 以平面可调五杆机构为主要研究对象 , 给定机构的尺寸参数 , 列出所 要分析机构的闭环矢量方程 , 使用 MATLAB 软件中 SIMULINK 仿真工具 , 在 SIMULINK 模型窗口下建立数…

UE4-光照重建

当我们拉入新的光源和模型到我们的场景中后&#xff0c;会产生这样的情况&#xff1a; Preview:预览 表示此时由于光照物体所产生的阴影都是预览级别的并不是真正的效果。 方法一&#xff1a; 或者也可以在世界大纲中选中我们的光源&#xff0c;然后将我们的光源改变为可以…

(MLLMs)多模态大模型论文分享(1)

Multimodal Large Language Models: A Survey 摘要&#xff1a;多模态语言模型的探索集成了多种数据类型&#xff0c;如图像、文本、语言、音频和其他异构性。虽然最新的大型语言模型在基于文本的任务中表现出色&#xff0c;但它们往往难以理解和处理其他数据类型。多模态模型…

“探求新质生产力 推进中国式现代化”学习交流活动在河北廊坊举办

7月21日&#xff0c;一场以“探求新质生产力 推进中国式现代化”为主题的学习交流活动在河北省廊坊市举办&#xff0c;2000余名企业界人士共同探讨企业发展的新路径与新动力。 7月21日&#xff0c;“探求新质生产力 推进中国式现代化”学习交流活动在河北省廊坊市举办。图为活动…

primeflex教学笔记20240720, FastAPI+Vue3+PrimeVue前后端分离开发

练习 先实现基本的页面结构: 代码如下: <template><div class="flex p-3 bg-gray-100 gap-3"><div class="w-20rem h-12rem bg-indigo-200 flex justify-content-center align-items-center text-white text-5xl"><input type=&q…

前端Vue组件化实践:自定义发送短信验证码弹框组件

在前端开发中&#xff0c;随着业务逻辑的日益复杂和交互需求的不断增长&#xff0c;传统的整体式开发方式逐渐暴露出效率低下、维护困难等问题。为了解决这些问题&#xff0c;组件化开发成为了一种流行的解决方案。通过组件化&#xff0c;我们可以将复杂的系统拆分成多个独立的…

JMeter:BeanShell到JSR223迁移中的注意事项

前言 在之前的文章JMeter&#xff1a;BeanShell向JSR223迁移过程遭遇的java标准库不可用问题-如何切换JDK版本中引用了一段使用BeanShell对入参进行加密的脚本&#xff0c;迁移到JSR223&#xff0c;虽然更换JDK后编译通过&#xff0c;看似也可以执行了&#xff0c;但是其实那段…

《0基础》学习Python——第二十讲__网络爬虫/<3>

一、用post请求爬取网页 同样与上一节课的get强求的内容差不多&#xff0c;即将requests.get(url,headershead)代码更换成requests.post(url,headershead),其余的即打印获取的内容&#xff0c;如果content-typejson类型的&#xff0c;打印上述代码的请求&#xff0c;则用一个命…

Linux 13:网络编程1

1. 预备知识 1-1. 理解源IP地址和目的IP地址 在IP数据包头部中&#xff0c;有两个IP地址&#xff0c;分别叫做源IP地址&#xff0c;和目的IP地址。 我们光有IP地址就可以完成通信了嘛&#xff1f;想象一下发qq消息的例子&#xff0c;有了IP地址能够把消息发送到对方的…