Spring IOC容器初始化过程及其原理(源码层面)

2023-11-06

Spring大家族在Java技术生态体系中占有重要地位,其中Spring更是其中的佼佼者。它极大的简化了我们的代码开发量,提高我们的工作效率。

其中Spring两大特性中的IOC特性是至关重要的。今天来从底层看一看Spring的容器的初始化过程。算是我的学习笔记,也希望能对你有所帮助!

(如果有不懂IOC的小伙伴们可以去看一看我前面写的文章传送门在此)。

在开始之前,先思考几个问题。

  • @Component,@Service,@Controller,@Repository@Bean等注解怎么实现的?
  • @Autowired,@Resource 是怎么自动装配的?
  • @ComponentScan 为什么就可以扫描注册Bean

 

对此我在其他博客看到一张图,感觉很生动形象。

IOC 容器 示意图

Spring IOC :

  1. Bean定义的定位,Bean 可以定义在XML中,或者一个注解,或者其他形式。这些都被用Resource来定位, 读取Resource获取BeanDefinition 注册到 Bean定义注册表中。
  2. 第一次向容器getBean操作会触发Bean的创建过程,实列化一个Bean时 ,根据BeanDefinition中类信息等实列化Bean.
  3. 将实列化的Bean放到单列Bean缓存内。
  4. 此后再次获取向容器getBean就会从缓存中获取。


 

OK,下面来看容器的初始化方法。

源码如下:

public void refresh() throws BeansException, IllegalStateException {
//同步代码块 。
        synchronized (this.startupShutdownMonitor) {
            // 准备刷新.
            prepareRefresh();
            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);
            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);
                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);
                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);
                // Initialize message source for this context.
                initMessageSource();
                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();
                // Initialize other special beans in specific context subclasses.
                onRefresh();
                // Check for listener beans and register them.
                registerListeners();
                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);
                // Last step: publish corresponding event.
                finishRefresh();
            }
            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }
                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();
                // Reset 'active' flag.
                cancelRefresh(ex);
                // Propagate exception to caller.
                throw ex;
            }
            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }

1. prepareRefresh 准备刷新

  • 设置启动时间,设计容器激活标志(active=true)
  • 初始化 properties 资源
  • 验证必须存在的properties(validateRequiredProperties)
  • 初始earlyApplicationEnvents.用于收集已经产生的ApplicationEnvents.

2.obtainFreshBeanFactory 获取容器

  • 调用子类的refeshBeanFactory(),SpringBoot中采用默认的实现,设置BeanFactorySerializationId,设置refreshed标志为true
  • 获取BeanFactory
  • XmlWebApplicationContext ,AnnotationConfigApplicationContext 会在这一步加载BeanDefinition
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring IOC容器初始化过程及其原理(源码层面) 的相关文章

随机推荐

  • Tomcat项目500报错处理方法之一

    今天做的项目出现了Tomcat500错误 根据错误提示是 java lang ClassNotFoundException 搜索了很多解决方法 最终找到一个解决方案 https blog csdn net u011008029 articl
  • 类#是公共的,应在名为#.java的文件中声明

    1 如果类A被声明为公共的 public 那么必须将类A保存在名为A java的文件中 2 反之 在一个文件中最多包含一个顶级的公共类 并且该公共类的名字与文件名相同 比如文件A java中 允许定义一个或多个类 但最多允许一个顶级的公共类
  • 又一波Microsemi招聘信息

    Position Manager ASIC Design Business Unit ESC PerformanceStorage Location Shanghai China Youwill build and lead an IC d
  • Deeplabcut----(3)新建自己的训练(多只动物)

    多动物的标注比单动物复杂了N倍 动物回来会穿梭 以至于一时不知道是哪只 需要对比着视频观看找对应的 1 打开deeplabcut 新建训练 2 编辑配置文件设置动物数量 关节 骨架等 单击Edit config file开始编辑 可以按照自
  • RT-DETR原理与简介(干翻YOLO的最新目标检测项目)

    概述与简介 RT DETR是一种实时目标检测模型 它结合了两种经典的目标检测方法 Transformer和DETR Detection Transformer Transformer是一种用于序列建模的神经网络架构 最初是用于自然语言处理
  • Hugging Face——MLM预训练掩码语言模型方法

    对于许多涉及 Transformer 模型的 NLP 程序 我们可以简单地从 Hugging Face Hub 中获取一个预训练的模型 然后直接在你的数据上对其进行微调 以完成手头的任务 只要用于预训练的语料库与用于微调的语料库没有太大区别
  • PHP CGI、FastCGI、PHP-FPM、PHP-CGI 区别

    PHP CGI FastCGI PHP FPM PHP CGI是不同的PHP执行方式和处理程序 它们有以下区别 PHP CGI Common Gateway Interface PHP CGI是一种通过CGI协议与Web服务器通信的PHP执
  • 基于 LSTM 的船舶轨迹预测,单步预测

    之前给的数据和代码可能有一些问题 现在从新修改一下 末尾提供数据集和源码链接 单步预测步长 10 单步循环预测长时间的位置 从第1个位置开始 前10个位置 真实位置 预测第11个位置 然后第2个位置到第11个位置 预测值 为一组 预测第12
  • c++20新特性

    个人博客地址 https cxx001 gitee io 前言 自C 11这个大版本更新以来 后来陆续有两次小版本迭代C 14 C 17 它们主要是对C 11的补充扩展 并没有增加太多大的特性 而这次的C 20 和当年C 11一样 又是一次
  • 用卷积神经网络实现表情识别

    用卷积神经网络实现表情识别 一 卷积神经网络简介 1 定义 2 结构 3 理论 4 性质 二 在python环境下实现 三 总结 一 卷积神经网络简介 1 定义 卷积神经网络 Convolutional Neural Networks CN
  • 吴恩达机器学习python作业之单变量线性回归

    第一个方法读取数据用的是pandas 第二个方法读数据用的是numpy 第一种方法是梯度下降法 第二种方法是正规方程法 跟着佬们的思路写写改改 如果有错误请私信或评论哦 数据集理解 ex1data1 txt的数据集是两列 第一列是popul
  • 炫酷的开关--20230907

    Night Day Toggle Completed It HTML div class controls div
  • Vue3 setup语法糖使用简易教程(下)

    Vue3 setup语法糖使用简易教程 下 前几天一个月薪35k的兄弟 给我推了一个人工智能学习网站 看了一段时间挺有意思的 包括语音识别 机器翻译等从基础到实战都有 很详细 分享给大家 1 组件 1 1组件引用 组件在props里直接引入
  • python configparser读取.conf配置文件获得配置信息

    configparser是用来读取配置文件的包 配置文件的格式如下 中括号 内包含的为system 下面为key value 的配置内容 web conf内容 1 py 内容 导入模块 import os configparser 读取文件
  • 今日头条号问答微头条原创收益向百粉开放

    今日头条号 问答和微头条原创收益向百粉作者开放了 以前没有还可以开通的作者 这次可以抓紧时间去申请开通 作者宋九九 头条号发布公告称 自2021 年 1 月 13 日起 微头条创作收益和问答创作收益权益面向粉丝数不低于100作者开放 只要你
  • Spring配置文件报错 application context not configured for this file

    Spring配置文件报错 application context not configured for this file 解决方法一 点击Configure application context 选择Create new applica
  • FileZilla Server 下载、安装、配置教程

    下载filezilla server filezilla server官网 FileZilla The free FTP solution https filezilla project org FileZilla Server下载 Fil
  • Python模块导入时全局变量"__all__"的作用

    Python中一个py文件就是一个模块 all 变量是一个特殊的变量 可以在py文件中 也可以在包的 init py中出现 1 在普通模块中使用时 表示一个模块中允许哪些属性可以被导入到别的模块中 如 全局变量 函数 类 如下 test1
  • 抓住czx【最短路】

    题目链接 首先 做这样的处理 把每个点的时间分割为几个区间 说明在这个区间内的时候 人在这个点内 那么 我们就有这样的选择 如果在这个区间内 或者区间之前抵达 就说明是可以碰见的 如果在这个区间之后抵达 就说明是见不到的了 所以跑最短路 如
  • Spring IOC容器初始化过程及其原理(源码层面)

    Spring大家族在Java技术生态体系中占有重要地位 其中Spring更是其中的佼佼者 它极大的简化了我们的代码开发量 提高我们的工作效率 其中Spring两大特性中的IOC特性是至关重要的 今天来从底层看一看Spring的容器的初始化过