Spring容器系列-启动原理(下)

news/2024/10/2 14:31:18

Spring容器系列-启动原理(下)

   从上一篇文章《Spring容器系列-启动原理(上)》中,介绍了Spring容器初始化的核心方法refresh()的整体情况。这篇文章来详细展开介绍。其中比较重要的方法会标记上***

   一、refresh中的12个方法

   1.  prepareRefresh

   主要作用:记录下容器启动时间,标记"已启动"状态
   2. obtainFreshBeanFactory ***

   主要作用:创建bean工厂,如果已经有则销毁,没有则创建。将配置文件解析成一个个 Bean 定义,注册到 BeanFactory中。

   里面实现对beanDefinition的装载(说到底核心是一个key为beanName,value为beanDefinition的 map)

   说明:获取到的是DefaultListableBeanFactory类的实例

   3. prepareBeanFactory ***

   主要作用:设置BeanFactory的类加载器,添加一些默认的后置处理器,添加默认的系统环境bean:环境配置、系统属性、系统环境变量

   说明:上一步obtainFreshBeanFactory已经把工厂建好了,但是还不能投入使用,因为工厂里什么都没有,还需要配置一些东西

   4. postProcessBeanFactory ***

   主要作用:空方法 - 模版方法,由子类重写。让子类有机会在BeanFactory准备就绪后对其进行进一步的处理或配置:例如添加自定义的BeanPostProcessor、注册特定类型的Bean等。

   说明:这里采用模版方法设计模式,空方法,留给子类来实现

   5. invokeBeanFactoryPostProcessors ***

   主要作用:在应用上下文中调用所有注册的 BeanFactoryPostProcessor 实现类的 postProcessBeanFactory 方法,以便对 BeanFactory 进行进一步的定制和处理

   说明:通常情况下,开发者可以通过实现 BeanFactoryPostProcessor 接口,在 postProcessBeanFactory 方法中编写自己的定制逻辑,以满足特定的需求。当调用 invokeBeanFactoryPostProcessors(beanFactory) 方法时,Spring 将自动扫描并调用所有注册的 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法,完成容器的预处理工作。

   6.  registerBeanPostProcessors ***

   主要作用:将自定义的配置文件中的BeanPostProcessor提取出来并注册进入beanFactory

   说明:这些后置处理器实现了 BeanPostProcessor 接口,用于在容器中的 Bean 创建、初始化、销毁等生命周期阶段进行特定操作。通过注册后置处理器,可以对容器中的 Bean 进行额外的处理,例如,AOP 切面的织入、自定义注解的处理、事件监听等。

   注册后置处理器是 Spring 框架实现灵活性和扩展性的重要手段之一,可以让开发者根据具体需求定制自己的处理逻辑,并将其无缝地集成到 Spring 容器中。

   在 Spring 中,注册后置处理器时会按照以下顺序进行排序:

   首先,将实现了 PriorityOrdered 接口的后置处理器添加到 priorityOrderedPostProcessors 集合中,并按照 Ordered 接口或 @Order 注解的顺序进行排序。

   然后,将实现了 Ordered 接口或使用 @Order 注解标注的后置处理器添加到 orderedPostProcessorNames 集合中。

   最后,将未实现以上接口或注解的后置处理器添加到 nonOrderedPostProcessorNames 集合中。

   后置处理器的类型包括:

   实现了 BeanPostProcessor 接口的后置处理器,用于在 Bean 实例化、依赖注入和初始化阶段对 Bean 进行额外的处理。

   实现了 BeanFactoryPostProcessor 接口的后置处理器,用于在 BeanFactory 标准初始化后对 BeanFactory 进行额外的处理。

   实现了 MergedBeanDefinitionPostProcessor 接口的后置处理器,用于在 Bean 定义合并前后对 Bean 进行额外的处理。

   MergedBeanDefinitionPostProcessor 接口是 BeanFactoryPostProcessor 的一个子接口,用于在 Bean 定义合并阶段进行操作,例如,可以通过这个后置处理器修改 Bean 的定义信息。

   7.  initMessageSource

   主要作用:初始化消息源,为 Spring 应用程序的国际化功能提供支持

   8.  initApplicationEventMulticaster

   主要作用:初始化事件管理类

   9.  onRefresh

   主要作用:模版方法,由子类重写。用于在容器刷新时执行特定的自定义操作:如创建Tomcat,Jetty等WEB服务器

   说明:在该方法中,可以添加任何希望在容器刷新完成后执行的逻辑,比如启动定时任务、初始化缓存、加载配置文件等等。通过重写这个方法,可以扩展容器刷新的行为,使得容器更适应特定的应用场景或业务需求。

   10.  registerListeners

   主要作用:注册监听器

   11.  finishBeanFactoryInitialization *** 

   主要作用:实例化所有剩余的(非懒加载)的单例 Bean

   12.  finishRefresh

 主要作用:完成应用程序的上下文刷新,其中包括:完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人


二、refresh()方法中比较重要的类/接口进行梳理

    1. BeanFactory 接口

    BeanFactory 是用于管理Bean的工厂,它负责创建、解析和管理Bean对象。在容器启动时,会先创建 BeanFactory,然后根据配置信息加载并初始化 Bean。

    2. BeanDefinition 接口

    Spring 实例化要通过 BeanDefinition。因为Class 是无法完成 bean 的抽象,比如 bean 的作用域,bean 的注入模型,bean 是否是懒加载等等信息,Class是无法抽象出来的,故而需要一个 BeanDefinition 类来抽象这些信息。

    BeanDefinition类图如下:


   3.  BeanDefinitionRegistry 接口

   BeanDefinitionRegistry 是 Spring 框架中的一个接口,用于注册和管理 BeanDefinition,即用于定义和描述 Spring 中的 Bean。

   BeanDefinitionRegistry 接口定义了一系列方法,包括注册、移除、检索 BeanDefinition 等。通过这些方法,可以向 Spring 容器注册各种类型的 BeanDefinition,包括单例、原型、懒加载等,并指定它们的依赖关系、作用域、初始化方法、销毁方法等。
通过使用 BeanDefinitionRegistry,开发人员可以动态地向 Spring 容器注册新的 BeanDefinition,从而实现灵活的 IoC(控制反转)和 DI(依赖注入)功能

 

registerBeanDefinition
往 BeanFactory 中注册 BeanDefinition

 


 

1)属性:beanDefinitionMap

 


 

/org/springframework/beans/factory/support/DefaultListableBeanFactory.java:164

 


 

private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

 


 

用于存储 Bean 名称和对应的 BeanDefinition 对象

 


 

2)方法:registerBeanDefinition()
负责管理 Spring IoC 容器中的 BeanDefinition,确保每个 Bean 都有一个唯一的名称,并处理覆盖和更新 BeanDefinition 的逻辑。

 

  4. ConfigurableListableBeanFactory 接口
   它继承自 ListableBeanFactory 和 ConfigurableBeanFactory 接口,主要用于配置和管理 BeanFactory。
总的来说,ConfigurableListableBeanFactory 提供了对 Spring IoC 容器的高级配置和管理功能,是 Spring 中 BeanFactory 的一个可配置的扩展接口。


   4.  DefaultListableBeanFactory 类

   它是Spring 框架中最常用的 IOC 容器实现之一,它支持 XML 配置和基于注解的配置,并提供了丰富的功能和灵活性,因此被广泛应用于各种类型的 Spring 应用中。

   它实现了 ConfigurableListableBeanFactory 和 BeanDefinitionRegistry 接口,提供了对 Bean 的定义和管理的基本功能。

   DefaultListableBeanFactory 是一个基本功能的 BeanFactory,它实现了 BeanDefinitionRegistry 接口。它的继承结构如下:

 

 

 

 


 

 


5. BeanDefinition 接口
BeanDefinition 用于描述和定义 Bean 的属性、行为以及依赖关系等信息。



6.BeanFactoryPostProcessor 接口
BeanFactoryPostProcessor 负责在 BeanFactory 加载 BeanDefinition 之后,但在 Bean 实例化之前,对 BeanFactory 进行后处理。这样可以在容器启动过程中对 BeanFactory 进行修改,比如注册自定义的 BeanDefinition,修改属性值,添加属性转换器等。



7. ApplicationContext 接口


ApplicationContext 实际上是 BeanFactory 的一个子接口,它扩展了 BeanFactory 的功能,提供了更多的企业级特性,比如国际化、事件发布、应用上下文的层级结构等。在 Spring 中,ApplicationContext 是 Spring IoC 容器的一种,而 BeanFactory 是 IoC 容器的基础接口。


ApplicationContext 不直接暴露 BeanFactory 的所有功能,而是通过代理模式对其进行封装和增强,使其具有更多的功能。这种封装和增强的方式让 ApplicationContext 具有了更强大的特性,比如自动装配、AOP(面向切面编程)、事件处理等,从而更适合于企业级应用的开发。


8. PostProcessorRegistrationDelegate 类
是 Spring 框架中用于处理后置处理器(BeanPostProcessor)的注册工具类。其主要作用是负责管理后置处理器的注册和执行顺序

 



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

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

相关文章

云原生打包工具-Buildpacks

云原生正在吞并软件世界,容器改变了传统的应用开发模式,如今研发人员不仅要构建应用,还要使用 Dockerfile 来完成应用的容器化,将应用及其依赖关系打包,从而获得更可靠的产品,提高研发效率。 随着项目的迭代,达到一定的规模后,就需要运维团队和研发团队之间相互协作。运…

uniapp计算字符串宽度

最近手机端聊天功能,想实现气泡框,根据输入的文本,背景颜色自动适应宽度本来呢,只需要在文本外包裹一个标签,不指定宽度,就能实现,但是nvue中文本只能写在text中,来实现字体大小颜色的设置,在使用text标签后就会导致文本框宽度直接就是最长 第一种方法: 所以需要计算…

服务器从hugging face下载数据集失败

问题 服务器没法下载外网数据导致hugging face的load_dataset下载失败。 解决方法 没找到load_dataset的源代码,想办法本地下载并上传到服务器,服务器从本地使用数据集。 示例:dataset = load_dataset("mit-han-lab/pile-val-backup", split="validation&quo…

微信小程序开发云环境,使用云函数实现通用印刷体识别, openapi.ocr.printedText

1.创建新项目时,要选中云开发,APPID不能使用测试号2.微信开发者工具,点击云开发,进行注册使用,刚开始是可以试用30天,之后是需要付费的。3.npm install --save wx-server-sdk@latest 终端安装此命令 https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/img…

ABC353F 分讨

回来补补题。 分析: 我先考虑 \(k\) 很大的时候,大块和大块间的移动,我们不得不尽量避免小块:我们容易发现这样时是最优的,可以发现就是在斜着走,也就是典型的切比雪夫距离。斜着走一次需要经过两条边,所以花费是两倍的切比雪夫距离。 要是起点和终点不在大块上呢? 首先…

数据可视化是如何在智慧水利中应用的?

数据可视化是如何在智慧水利中应用的?在现代水利管理中,面对复杂的水资源数据和动态变化的水文情况,数据可视化技术通过将繁杂的数据转化为直观、易理解的图表和图形,极大地提升了水利管理的效率和决策的科学性。智慧水利利用数据可视化技术,实现了对水资源的全面监控、精…

CloudEvents-云原生事件规范

简介 CloudEvents 是一种定义事件数据在云端应用之间如何交付的规范,这是由 Cloud Native Computing Foundation(CNCF)的 Serverless 工作小组开发的。通过提供统一的事件格式,CloudEvents 旨在简化跨服务、平台和供应商的事件交付。 CloudEvents位于CNCF全景图的”流和消息…

MyBatisX插件生成代码

MyBatisX插件 MyBatis Plus提供了一个IDEA插件——MybatisX,使用它可根据数据库快速生成Entity、Mapper、Mapper.xml、Service、ServiceImpl等代码,使用户更专注于业务。 下面演示具体用法安装插件在IDEA插件市场搜索MyBatisX,进行在线安装配置数据库连接在IDEA中配置数据库连…