什么是refresh?Spring refresh 流程
refresh 是 AbstractApplicationContext 中的一个方法,负责初始化 ApplicationContext 容器,容器必须调用 refresh 才能正常工作。它的内部主要会调用 12 个方法,我们把它们称为 refresh 的 12 个步骤:
1. prepareRefresh
2. obtainFreshBeanFactory
3. prepareBeanFactory
4. postProcessBeanFactory
5. invokeBeanFactoryPostProcessors
6. registerBeanPostProcessors
7. initMessageSource
8. initApplicationEventMulticaster
9. onRefresh
10. registerListeners
11. finishBeanFactoryInitialization
12. finishRefresh
功能分类
1 为准备环境
2 3 4 5 6 为准备 BeanFactory
7 8 9 10 12 为准备 ApplicationContext
11 为初始化 BeanFactory 中非延迟单例 bean
具体步骤
1. prepareRefresh
* 这一步创建和准备了 Environment 对象,它作为 ApplicationContext 的一个成员变量
* Environment 对象的作用之一是为后续 @Value,值注入时提供键值
* Environment 分成三个主要部分
* systemProperties - 保存 java 环境键值
* systemEnvironment - 保存系统环境键值
* 自定义 PropertySource - 保存自定义键值,例如来自于 *.properties 文件的键值

2. obtainFreshBeanFactory
* 这一步获取(或创建) BeanFactory,它也是作为 ApplicationContext 的一个成员变量
* BeanFactory 的作用是负责 bean 的创建、依赖注入和初始化,bean 的各项特征由 BeanDefinition 定义
* BeanDefinition 作为 bean 的设计蓝图,规定了 bean 的特征,如单例多例、依赖关系、初始销毁方法等
* BeanDefinition 的来源有多种多样,可以是通过 xml 获得、配置类获得、组件扫描获得,也可以是编程添加
* 所有的 BeanDefinition 会存入 BeanFactory 中的 beanDefinitionMap 集合

3. prepareBeanFactory
* 这一步会进一步完善 BeanFactory,为它的各项成员变量赋值
* beanExpressionResolver 用来解析 SpEL,常见实现为 StandardBeanExpressionResolver
* propertyEditorRegistrars 会注册类型转换器
* 它在这里使用了 ResourceEditorRegistrar 实现类
* 并应用 ApplicationContext 提供的 Environment 完成 ${ } 解析
* registerResolvableDependency 来注册 beanFactory 以及 ApplicationContext,让它们也能用于依赖注入
* beanPostProcessors 是 bean 后处理器集合,会工作在 bean 的生命周期各个阶段,此处会添加两个:
* ApplicationContextAwareProcessor 用来解析 Aware 接口
* ApplicationListenerDetector 用来识别容器中 ApplicationListener 类型的 bean

4. postProcessBeanFactory
* 这一步是空实现,留给子类扩展。
* 一般 Web 环境的 ApplicationContext 都要利用它注册新的 Scope,完善 Web 下的 BeanFactory
* 这里体现的是模板方法设计模式
5. invokeBeanFactoryPost Processors
* 这一步会调用 beanFactory 后处理器
* beanFactory 后处理器,充当 beanFactory 的扩展点,可以用来补充或修改 BeanDefinition
* 常见的 beanFactory 后处理器有
* ConfigurationClassPostProcessor – 解析 @Configuration、@Bean、@Import、@PropertySource 等
* PropertySourcesPlaceHolderConfigurer – 替换 BeanDefinition 中的 ${ }
* MapperScannerConfigurer – 补充 Mapper 接口对应的 BeanDefinition

6. registerBeanPost Processors
* 这一步是继续从 beanFactory 中找出 bean 后处理器,添加至 beanPostProcessors 集合中
* bean 后处理器,充当 bean 的扩展点,可以工作在 bean 的实例化、依赖注入、初始化阶段,常见的有:
* AutowiredAnnotationBeanPostProcessor 功能有:解析 @Autowired,@Value 注解
* CommonAnnotationBeanPostProcessor 功能有:解析 @Resource,@PostConstruct,@PreDestroy
* AnnotationAwareAspectJAutoProxyCreator 功能有:为符合切点的目标 bean 自动创建代理

7. initMessageSource
* 这一步是为 ApplicationContext 添加 messageSource 成员,实现国际化功能
* 去 beanFactory 内找名为 messageSource 的 bean,如果没有,则提供空的 MessageSource 实现

8. initApplication ContextEventMulticaster
* 这一步为 ApplicationContext 添加事件广播器成员,即 applicationContextEventMulticaster
* 它的作用是发布事件给监听器
* 去 beanFactory 找名为 applicationEventMulticaster 的 bean 作为事件广播器,若没有,会创建默认的事件广播器
* 之后就可以调用 ApplicationContext.publishEvent(事件对象) 来发布事件

9. onRefresh
* 这一步是空实现,留给子类扩展
* SpringBoot 中的子类在这里准备了 WebServer,即内嵌 web 容器
* 体现的是模板方法设计模式
10. registerListeners
* 这一步会从多种途径找到事件监听器,并添加至 applicationEventMulticaster
* 事件监听器顾名思义,用来接收事件广播器发布的事件,有如下来源
* 事先编程添加的
* 来自容器中的 bean
* 来自于 @EventListener 的解析
* 要实现事件监听器,只需要实现 ApplicationListener 接口,重写其中 onApplicationEvent(E e) 方法即可

11. finishBeanFactory Initialization
* 这一步会将 beanFactory 的成员补充完毕,并初始化所有非延迟单例 bean
* conversionService 也是一套转换机制,作为对 PropertyEditor 的补充
* embeddedValueResolvers 即内嵌值解析器,用来解析 @Value 中的 ${ },借用的是 Environment 的功能
* singletonObjects 即单例池,缓存所有单例对象
* 对象的创建都分三个阶段,每一阶段都有不同的 bean 后处理器参与进来,扩展功能

12. finishRefresh
* 这一步会为 ApplicationContext 添加 lifecycleProcessor 成员,用来控制容器内需要生命周期管理的 bean
* 如果容器中有名称为 lifecycleProcessor 的 bean 就用它,否则创建默认的生命周期管理器
* 准备好生命周期管理器,就可以实现
* 调用 context 的 start,即可触发所有实现 LifeCycle 接口 bean 的 start
* 调用 context 的 stop,即可触发所有实现 LifeCycle 接口 bean 的 stop
* 发布 ContextRefreshed 事件,整个 refresh 执行完成

相关文章:
什么是refresh?Spring refresh 流程
refresh 是 AbstractApplicationContext 中的一个方法,负责初始化 ApplicationContext 容器,容器必须调用 refresh 才能正常工作。它的内部主要会调用 12 个方法,我们把它们称为 refresh 的 12 个步骤:1. prepareRefresh2. obtain…...
Python登陆系统
前言 #源码见文末公众号哈# 登录系统 一个简单的登录系统包含了登录账户、注册账户、修改密码以及注销账户的操作。 1. 登录账户 登录系统主要需要判断账户是否存在,不存在就注册一个账户,如果第一次登录系统,我们需要先新建一个文件&…...
【新2023】华为OD机试 - 重组字符串(Python)
华为 OD 清单查看地址:blog.csdn.net/hihell/category_12199275.html 重组字符串 题目 给定一个非空字符串 S,其被 N 个‘-’分隔成 N+1 的子串,给定正整数 K, 要求除第一个子串外,其余的子串每 K 个字符组成新的子串,并用‘-’分隔。 对于新组成的每一个子串,如果它…...
视频监控流程图
<html> <head> <meta http-equiv"Content-Type" content"text/html; charsetUTF-8"/> <link rel"stylesheet" type"text/css" href"visio.css"/> <title> 视频监控流程图 </title> <…...
普通单双面板的生产工艺流程之图形转移,华秋一文告诉你
衔接上文,继续为朋友们分享普通单双面板的生产工艺流程。 如图,第五道主流程为图形转移。 图形转移的目的为: 利用光化学原理,将图形线路的形状转移到印制板上,再利用化学原理,将图形线路在印制板上制作出…...
1.8 providers
生成providersnest g service <name>providers的注入方式构造函数注入Injectable() export class KeywordService {constructor(private readonly httpService: HttpService,private readonly pro: ProService,) {} }Inject()注入export class KeywordController {Inject…...
如何编写一个基本的 Verilog Module(模块)
1、概述这篇文章主要介绍了 Verilog 在 FPGA 设计中的概念和使用方法。首先讨论使用模块(module)关键字构造 Verilog 设计的方式,以及这与所描述的硬件的关系。这包括对参数、端口(port)和例化(instantiato…...
让乔布斯想要「发动核战争」的 Android,为何成了占有率最高的系统?
2008 年 9 月 23 日,Apple 的创始人和 CEO 史蒂夫乔布斯像往常一样走进了公司,此时距离初代 iPhone 的发布会才过了一年半,这款充满了争议的产品就像一块从山崖滚落的巨岩,一路电光石火的给手机市场的《小石潭记》来了场焚书坑儒。…...
FPGA开发软件(vivado + modelsim)环境搭建(附详细安装步骤+软件下载)
本文详细介绍了vivado软件和modelsim软件的安装,以及vivado中配置modelsim仿真设置,每一步都加文字说明和图片。一、软件安装包下载1、vivado vivado版本很多,目前最新的已更新到vivado2022.2,版本越高,安装包越大&…...
TypeScript 学习之类型
布尔类型 类型: boolean最简单的类型,值只有 true/false let isDone: boolean true;数字类型 类型:number数字都是浮点数,支持二进制、八进制、十进制、十六进制。 let decLiteral: number 16; // 十进制 let hexLiteral: number 0xf0…...
基于MATLAB计算MIMO信道容量(附完整代码与分析)
目录 一.介绍 二. 代码 三. 运行结果及分析 3.1 MIMO信道容量:固定发射天线数为4 3.2 MIMO信道容量:固定接收天线数为4 3.3 AWGN信道与瑞利信道容量 四. 总结 一.介绍 本文章将在MATLAB环境中分析MIMO信道容量,AWGN信道容量…...
CSDN城市开发者联盟、C友会期待你的加入
文章目录🌟 课前小差🌟 chatGPT🌟 CSDN中的持续学习🌟 23年原力计划🌟 C友会、CDC🌟 如何关联本地的开发者?🌟 写在最后🌟 课前小差 哈喽,大家好,…...
【新2023】华为OD机试 - 吃火锅(Python)
华为 OD 清单查看地址:blog.csdn.net/hihell/category_12199275.html 吃火锅 题目 入职后,导师会请你吃饭,你选择了火锅, 火锅里会在不同时间下很多菜, 不同食材要煮不同时间,才能变得刚好合适, 你希望吃到最多的刚好合适的菜, 但是你的手速不够快用m代替手速, 每次…...
类似LeetCode的登录页面(小程序版)
前言每一个项目都会有用户端的注册和登录页面,对于刚入门的小白来说,在UI设计方面不太擅长,就算大致的UI界面设计出来了,但是落实到代码上来实现的时候就很容易卡住。这篇博客主要介绍的就是仿作一个类似LeetCode登录的简约大方页…...
CUDA的统一内存
CUDA的统一内存 文章目录CUDA的统一内存N.1. Unified Memory IntroductionN.1.1. System RequirementsN.1.2. Simplifying GPU ProgrammingN.1.3. Data Migration and CoherencyN.1.4. GPU Memory OversubscriptionN.1.5. Multi-GPUN.1.6. System AllocatorN.1.7. Hardware Coh…...
MySQL-其他函数(补充)
格式化函数FORMAT(x, n) 例:将数字x进行格式化,以四舍五入的方式保留n位小数,结果以字符串的形式返回mysql> select format(12.3456,3),format(2.2,4),format(9.333,0); --------------------------------------------------- | format(12…...
MySQL Study Notes Design in 2023
文章目录1 概述1.1 MySQL相关概述1.2 数据模型1.3 SQL分类2 数据库设计-DDL2.1 约束2.2 字段3 数据库操作-DML3.1 增加(insert)1 概述 1.1 MySQL相关概述 数据库:英文为 DataBase,简称DB,它是存储和管理数据的仓库。 数据库管理系统…...
C++ 修改防火墙firewall设置(Windows)
文章目录1、简介1.1 防火墙概述1.2 入站,还是出站?1.3 防火墙规则优先级2、系统界面方式3、命令行方式3.1 防火墙基本状态设置3.2 入站出站规则设置3.3 其他设置3.4 telnet检测端口4、C方式4.1 注册表4.2 COM(Windows XP)4.3 COM&…...
Spring 入门教程详解
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
day43【代码随想录】动态规划之一和零、完全背包理论基础
文章目录前言一、一和零(力扣474)二、完全背包前言 1、一和零 2、完全背包理论基础 一、一和零(力扣474) 求装满这个背包最多有多少个物品 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
