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

news2024/9/20 16:59:39

前言:

本文整体框架是通过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("销毁");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean方法执行");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("BeanNameAware方法执行");
    }

    @Override
    public 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 {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if("a".equals(beanName)){
            System.out.println(beanName+"我是后处理器的before方法");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if("a".equals(beanName)) {
            System.out.println(beanName + "我是后处理器的after方法");
        }
        return bean;
    }
}
4:创建测试类测试:
class BeanTestTest {


    @Test
    public 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.coloradmin.cn/o/1943956.html

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

相关文章

go语言day14 bufio包 ioutil包

Golang-100-Days/Day16-20(Go语言基础进阶)/day16_file操作.md at master rubyhan1314/Golang-100-Days GitHub 一、bufio包 读写文件 1&#xff09; bufio包下的Reader类实现了Read()方法和Write()方法 2&#xff09;和io包相比&#xff0c;虽然都是在读写文件&#xff0c;…

【SQL】字段筛选出含有某些关键词,模糊匹配LIKE的用法

如果我们要查询数据库中&#xff0c;某个字段含有一些文字&#xff0c;例如查名字的时候&#xff0c;查询开头含有某些姓氏的人&#xff0c;或者查询以某些符号结尾的文字&#xff0c;都可以用模糊匹配来查询字段&#xff0c;WHERE子句LIKE 的操作符搜索。 以下是一些使用示例…

开源XDR-SIEM一体化平台 Wazuh (2)安装

简介 安装 Wazuh indexer 可以根据具体需求和环境选择多种方法。可以通过脚本安装&#xff0c;也可以通过yum/apt等安装工具进行安装&#xff0c;详细安装方式可以参考Wazuh documentation官方文档。 即除了上述的安装方式外&#xff0c;还可以通过集成式的镜像进行运行。可以…

Mac 中安装内网穿透工具ngrok

ngrok 是什么&#xff1f; Ngrok 是一个网络工具&#xff0c;主要用于在网络中创建从公共互联网到私有或本地网络中运行的web服务的安全隧道。它充当了一个反向代理&#xff0c;允许外部用户通过公共可访问的URL访问位于防火墙或私有网络中的web应用程序或服务。Ngrok 特别适用…

Mindspore框架循环神经网络RNN模型实现情感分类|(二)词向量

Mindspore框架循环神经网络RNN模型实现情感分类 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;一&#xff09;IMDB影评数据集准备 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;二&#xff09;预训练词向量 Mindspore框架循环神经网络RNN模型实现…

大模型额外篇章三:vercel搭建openai中转服务器

文章目录 一、起因和注意1)起因2)注意二、实现方法(原理:透传)1)nginx方案2)node服务3)纯 js 方案4)选择国外的域名服务商(DNS 解析路径缩短,建议方案国外提供 CDN 云服务商结合自建云服务业务做负载均衡)三、实践(vercel部署OpenAI代理服务器)四、测试搭建的Ope…

UE4 自动换行——按排序关键字1.2.3.

要自动换行的字符串举例&#xff1a;“有效节点为:1.demo-worker-02 2.demo-worker-01 3.demo-master-01” 1.获取相邻两位字符串&#xff0c;组合后与关键字比较 2.当两位字符串与关键字相等&#xff0c;附加一次换行 3.其他例如 1)2)3)、(1)(2)(3)、<1><2><…

XLua 原理分析 三

前面已经介绍了Lua与C#的基础通信原理&#xff0c;和Wrap中间文件的作用。有了前面2篇的基础&#xff0c;大概已经能搞清这块的原理。 为了加深对这块的印象&#xff0c;这里开始正式分析Xlua中的Lua和C#的通信。 一、Lua如何调用CS的过程 lua的初始化代码&#xff1a; pri…

驱动开发系列06 - 内存映射和DMA

目录 一:概述 二:Linux中的内存管理 地址类型 物理地址与页 高内存和低内存 内存映射和页结构体 页表 虚拟内存区域 vm_area_struct 结构 进程内存映射 三:mmap 设备操作 使用 remap_pfn_range 一个简单的实现 添加 VMA 操作 使用 nopage 映射内存 重新映射特定 I/O…

QT5.9.9+Android开发环境搭建

文章目录 1.安装准备1.1 下载地址1.2 安装前准备2.安装过程2.1 JDK安装2.1.1 安装2.1.2 环境变量配置2.2 SDK配置2.2.1 安装2.2.2 环境变量配置2.2.3 adb 错误解决2.2.4 其他SDK安装2.2.5 AVD虚拟机配置2.3 NDK配置2.4 QT 5.9.9安装配置2.4.1 QT安装2.4.2 配置安卓环境3.QT工程…

Android Kotlin:协程

目录&#xff1a; 1&#xff09;协程是什么&#xff1f; 2&#xff09;协程和线程的关系&#xff1f; 3&#xff09;协程如何使用&#xff1f;切线程是什么 4&#xff09;挂起函数是什么&#xff1f; 5&#xff09;withContext和lanuch的区别在哪里&#xff1f; 6&#xff09;…

某矿webpack逆向

免责声明&#xff1a; 本篇博文的初衷是分享自己学习逆向分析时的个人感悟&#xff0c;所涉及的内容仅供学习、交流&#xff0c;请勿将其用于非法用途&#xff01;&#xff01;&#xff01;任何由此引发的法律纠纷均与作者本人无关&#xff0c;请自行负责&#xff01;&#xf…

华媒舍:6个媒体宣发套餐,快速突破传播界限

在当今信息爆炸的社会中&#xff0c;有效地传播自己的信息变得愈发困难。特别是对于媒体宣发来说&#xff0c;如何在市场竞争激烈的情况下突破传播界限&#xff0c;让自己的消息传达给更多的人&#xff0c;这是每个企业和个人都面临的难题。 为了解决这个问题&#xff0c;我们推…

图片变更检测

20240723 By wdhuag 目录 前言&#xff1a; 参考&#xff1a; 文件监控&#xff1a; 图片占用问题&#xff1a; 源码&#xff1a; 前言&#xff1a; 由于第三方图像处理软件不能回传图片&#xff08;正常都能做&#xff0c;这里只是不想做&#xff09;&#xff0c;只能在…

有什么好用的AI工具推荐吗?

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/ 所有打工人集合&#xff01;根据你问题中的描述&#xff0c;本小白正好都有涉及过相关领域的AI工具。 今天一次性讲清能处理所有办公场景的AI工具…

Harmony学习(二)------ArkUI(2)

1.主轴对齐方式.justifyContent build() {Column(){Text().width(200).height(100).backgroundColor(Color.Yellow).border({width:2})Text().width(200).height(100).backgroundColor(Color.Yellow).border({width:2}).margin(10)Text().width(200).height(100).backgroundCol…

现货黄金布林线怎么看?又应如何使用?

在现货黄金投资中&#xff0c;技术指标是很多人做交易分析和决策时所需要的工具。当然&#xff0c;由于电脑技术的发达&#xff0c;现在各种技术指标已经有成千上万种&#xff0c;其中一些经典的指标还是很受市场欢迎&#xff0c;比方说布林线。下面我们就来简单地介绍布林线在…

【调试笔记-20240723-Linux-gitee 仓库同步 github 仓库,并保持所有访问链接调整为指向 gitee 仓库的 URL】

调试笔记-系列文章目录 调试笔记-20240723-Linux-gitee 仓库同步 github 仓库&#xff0c;并保持所有访问链接调整为指向 gitee 仓库的 URL 文章目录 调试笔记-系列文章目录调试笔记-20240723-Linux-gitee 仓库同步 github 仓库&#xff0c;并保持所有访问链接调整为指向 gite…

Python爬虫(5) --爬取网页视频

文章目录 爬虫爬取视频指定url发送请求UA伪装请求页面 获取想要的数据解析定位定位音视频位置 存放视频完整代码实现总结 爬虫 Python 爬虫是一种自动化工具&#xff0c;用于从互联网上抓取网页数据并提取有用的信息。Python 因其简洁的语法和丰富的库支持&#xff08;如 requ…

typora激活问题

不使用激活码解决。 1.右键桌面图标&#xff0c;打开文件位置 2.按照 Typora路径到 —> resources —> page-dist —> static —> js 这个路径找到这两个文件 LicenseIndex.180dd4c7.xxxxxxx.chunk.js LicenseIndex.180dd4c7.xxxxxxx.chunk.js &#xff08;也可…