spring ioc源码-refresh();

主要作用是刷新应用上下文

@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 启动刷新的性能跟踪步骤StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");// 准备刷新,设置标志位,保存了容器的启动时间prepareRefresh();// 子类实现,获取一个新的 BeanFactoryConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 准备 BeanFactory,设置一些基本的配置prepareBeanFactory(beanFactory);try {// 允许子类对 BeanFactory 进行进一步的处理postProcessBeanFactory(beanFactory);// 启动性能跟踪步骤,执行在容器中注册的 BeanFactoryPostProcessorsStartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");invokeBeanFactoryPostProcessors(beanFactory);// 注册 BeanPostProcessors,这些 processors 会拦截 Bean 的创建过程registerBeanPostProcessors(beanFactory);beanPostProcess.end();// 初始化消息源initMessageSource();// 初始化事件广播器initApplicationEventMulticaster();// 子类实现,初始化一些特殊的 beansonRefresh();// 注册监听器 beansregisterListeners();// 实例化所有剩余的(非懒加载的)单例 beansfinishBeanFactoryInitialization(beanFactory);// 最后一步:发布相应的事件finishRefresh();} catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// 销毁已创建的单例 beans,以避免悬空资源destroyBeans();// 重置 'active' 标志位cancelRefresh(ex);// 将异常传播给调用者throw ex;} finally {// 重置 Spring 核心中的常见内省缓存,因为我们可能不再需要单例 beans 的元数据了resetCommonCaches();// 结束性能跟踪步骤contextRefresh.end();}}
}

主要就做了这些,对上面的方法进行分解:

prepareRefresh():

主要就是保存了启动时间,启动标志

protected void prepareRefresh() {// Switch to active.this.startupDate = System.currentTimeMillis();this.closed.set(false);this.active.set(true);//....省略部分代码}
prepareBeanFactory  
做准备工作
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the context's class loader etc.//设置类加载器		
beanFactory.setBeanClassLoader(getClassLoader());if (!shouldIgnoreSpel) {beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));}beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.//添加后置处理器:ApplicationContextAwareProcessorbeanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));//忽略自动装配beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);// BeanFactory interface not registered as resolvable type in a plain factory.//以下接口,允许自动装配,第一个参数是自动装配的类型,,第二个字段是自动装配的值// MessageSource registered (and found for autowiring) as a bean.beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// Register early post-processor for detecting inner beans as //添加一个后置处理器:ApplicationListenerDetector,此后置处理器实现了BeanPostProcessor接口
ApplicationListeners.beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// Detect a LoadTimeWeaver and prepare for weaving, if found.if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// Set a temporary ClassLoader for type matching.beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// Register default environment beans.//在容器中还没有XX的bean的时候,帮我们注册beanName为XX的singleton beanif (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());}if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());}if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());}}

invokeBeanFactoryPostProcessors(beanFactory);

主要逻辑代码在org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)

代码设计太多就不粘贴了,主要做了一下逻辑:

  1. 初始化设置:

    • 该方法接收一个 ConfigurableListableBeanFactory 和一个 BeanFactoryPostProcessor 实例的列表。
  2. 处理 BeanDefinitionRegistryPostProcessor 实例:

    • 如果 beanFactory 也是 BeanDefinitionRegistry(用于管理 bean 定义的扩展接口),则该方法区分常规的 BeanFactoryPostProcessors 和实现了 BeanDefinitionRegistryPostProcessor 的处理器。
    • 它遍历提供的 beanFactoryPostProcessors,对于实现了 BeanDefinitionRegistryPostProcessor 接口的实例,调用其 postProcessBeanDefinitionRegistry 方法,并将它们收集到不同的列表中。
  3. 按顺序处理 BeanDefinitionRegistryPostProcessor

    • 该方法按照三个阶段处理 BeanDefinitionRegistryPostProcessor:PriorityOrdered、Ordered 和其他处理器。
    • 对于每个阶段,它获取相关的后置处理器名称,实例化它们,根据它们的优先级或顺序排序,并调用它们的 postProcessBeanDefinitionRegistry 方法。
  4. 处理已注册的 BeanFactoryPostProcessor 实例:

    • 如果 beanFactory 不是 BeanDefinitionRegistry,则直接调用已注册的 BeanFactoryPostProcessor 实例。
  5. 按顺序处理 BeanFactoryPostProcessor

    • 该方法根据实现 PriorityOrderedOrdered 和其他接口的 BeanFactoryPostProcessor 分别处理。
    • 首先,调用实现了 PriorityOrdered 接口的后置处理器。
    • 接着,调用实现了 Ordered 接口的后置处理器。
    • 最后,调用所有其他 BeanFactoryPostProcessor
  6. 清除缓存的合并 bean 定义:

    • 由于后置处理器可能已修改原始元数据,例如替换值中的占位符,因此清除缓存的合并 bean 定义。

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

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

相关文章

Typescript面向对象

面向对象 面向对象是程序中一个非常重要的思想&#xff0c;它被很多同学理解成了一个比较难&#xff0c;比较深奥的问题&#xff0c;其实不然。面向对象很简单&#xff0c;简而言之就是程序之中所有的操作都需要通过对象来完成。 举例来说&#xff1a; 操作浏览器要使用windo…

Windows 10启用Hyper-V

Windows 10启用Hyper-V 官网教程PowerShell 启用 Hyper-V启用 Hyper-V 角色 我们知道VMware是创建虚拟机的好工具&#xff0c;那Windows平台上有没有虚拟工具呢&#xff1f; 今天我们要讲解的就是Windows才入局的虚拟工具&#xff1a;Hyper-V 官网教程 https://learn.microsof…

2024年的学习规划和碎碎念

2023最后一天&#xff0c;仿佛都要将自己变成小孩子&#xff0c;在等待新的一年。春节与我的意义不大&#xff0c;我反而期待元旦&#xff0c;好似跨过去&#xff0c;我就蜕变成新的人啦&#xff0c;全身血液换了个变&#xff0c;人也不是之前的灵魂。 当然那不可能。回顾自己…

table表格中使用el-popover 无效问题解决

实例只针对单个的按钮管用在表格里每一列都有el-popover相当于是v-for遍历了 所以我们在触发按钮的时候并不是单个的触发某一个 主要执行 代码 <el-popover placement"left" :ref"popover-${scope.$index}"> 动态绑定了ref 关闭弹窗 执行deltask…

【数据结构和算法】找出两数组的不同

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 哈希类算法题注意事项 2.2 方法一&#xff1a;哈希法 三、代码 3.1 方法一&#xff1a;哈希法 四…

Linux文件类型

在 Linux 系统中&#xff1a; b 文件类型&#xff1a;代表块设备文件。块设备文件通常是对应于设备&#xff0c;如硬盘驱动器或其他块设备&#xff0c;使用块级别的 I/O 操作。 c 文件类型&#xff1a;代表字符设备文件。字符设备文件通常是对应于设备&#xff0c;如串口、键盘…

[年终总结]人生就是大闹一场

讲真的,感觉过去这一年的体验,非常精彩,哈哈哈哈 体验了 裸辞,并没有想象中那么可怕,也没有想象中那么焦虑 经历了 入职之后又被裁员,心情没有那么大的起伏 解锁了 深圳/佛山/珠海/澳门/昆明/大理/新疆/成都 ,见了很多人,碰撞出了很多 idea 体会了 没有目的的去做一件事情,是什…

GitHub的2FA验证问题解决工具

文章目录 前言认识2FA开源工具使用&#xff1a;AuthenticatorPro获取AuthenticatorPro的安卓APK如何使用 参考文章 前言 打开GitHub跳出来这个提示&#xff0c;需要进行验证&#xff1a; 如何解决呢&#xff1f;方案有很多&#xff0c;我们可以使用开源的一个工具&#xff1a;…

vue 动态添加style样式

示例1 <div class"qrcode" :style"{display: qrcodeShow?:none}"><img src"../assets/images/qrcode.jpg"> </div>{display: qrcodeShow?:none} 为JS对象。 示例2 <div class"qrcode" :style"qrcodeSt…

爬虫工作量由小到大的思维转变---<第三十一章 Scrapy Redis 初启动/conn说明书)>

前言: 重点在读connection.py的源码,这个组件主要是用来连接的; 因为连接都无法做到,后面想更改点自定义就白扯了; 正文: 翻译版的connection.py源码: import sys import six from scrapy.utils.misc import load_object from . import defaults# 快捷方式映射 设置名称 -&…

Kotlin 属性

1、声明 关键字 var 声明为可变的 关键字 val 声明为只读的 class Address {val name: String "Holmes, Sherlock"val street: String "Baker"var city: String "London"var state: String? nullvar zip: String "123456" } …

RedisCache——redis缓存工具类

SuppressWarnings(value { “unchecked”, “rawtypes” }) Component public class RedisCache { Autowired public RedisTemplate redisTemplate; /*** 缓存基本的对象&#xff0c;Integer、String、实体类等** param key 缓存的键值* param value 缓存的值*/ public <T…

Java工厂模式详解

Java工厂模式详解 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;让我们一起深入研究Java中的一项关键设计模式——工厂模式。工厂模式是一种创建型…

java图书管理系统

主要模块&#xff1a; 为用户开通借书服务增加图书信息登记图书借出信息 技术栈&#xff1a; JSPServletTomcat9.0IDEAMysql 前台登录验证使用框架 数据库脚本包括登录用户名和密码已经写在了数据库脚本.sql 中 解压“需要的jar包”添加到项目的dependency中 运行效果&a…

mac安装yum

1. 安装brew /bin/zsh -c “$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)” 安装成功 但还需要重启终端 或者 运行 source /Users/wangjun/.zprofile 否则可能无法使用 2. 安装yum brew install yum

2023年度总结———豫见及遇见

目录 一.AI 人工智能方向 二.华为数通网络方向 三.腾讯云AI绘画方向 四.年度心得总结板块 博主C站主页&#xff1a;知孤云出岫_网络,计算机,计算机网络教案-CSDN博客 博主腾讯云主页&#xff1a; 知孤云出岫 - 个人中心 - 腾讯云开发者社区-腾讯云 2023年年度词&#xff1a…

移动端开发框架mui代码在安卓模拟器上运行(HbuilderX连接到模拟器)

开发工具 HBuilder X 3.8.12.20230817 注意&#xff1a;开发工具尽量用最新的或较新的。太旧的版本在开发调试过程中可能会出现莫名其妙的问题。 1、电脑下载安装安卓模拟器 我这里使用的是 夜神模拟器 &#xff0c;也可以选择其他安卓模拟器 夜神模拟器官网&#xff1a;夜神安…

阿贝云免费云服务器

最近体验了一下阿贝云的免费云服务器&#xff0c;总体感受是简单易上手。感兴趣的小伙伴们可以赶紧注册体验一下。 阿贝云官网&#xff1a; https://www.abeiyun.com 下图是我亲测的免费云服务器管理界面&#xff0c;免费云服务器的配置信是1核1GB&#xff0c;硬盘10GB&#x…

ssm基于web的马病管理系统设计与实现+jsp论文

摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;马病信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行处理不能满足广大…

R语言【CoordinateCleaner】——cc_urb(): 根据地理地名词典从城市区域内删除或标记记录。

Package CoordinateCleaner version 2.0-20 Parameters cc_urb(x,lon "decimallongitude",lat "decimallatitude",ref NULL,value "clean",verbose TRUE ) 参数【x】&#xff1a;data.frame。包含地理坐标和物种名称。 参数【lon】&…