AbstractApplicationContext的refresh方法

AbstractApplicationContext.refresh()应用上下文刷新方法 前情提要: 学习源码光看博客文章基本没有记住的可能.结合源码和博客+实践才能够通过理解记住,看了很多天才断断续续看完,发现它和其他IOC、Bean生命周期都有关联,将之前片段式的认知串联起来了. 这个刷新的代码很长,建议没耐心的时候就先不看,但是每天固定一个时间看一会,熟练了再串联起来看一遍. 上下文刷新方法被调用时机是SpringBoot.run启动中上下文准备方法(prepareContext)执行完毕后进行同步调用的 上下文准备方法(prepareContext)主要执行SpringApplica 阅读详情

AbstractApplicationContext的refresh方法


        AbstractApplicationContext的refresh是Spring IOC容器启动的整个过程,这里记录下refresh方法做的一些事情。

代码如下:

@Override
	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();
			}
		}
	}

prepareRefresh

刷新前准备工作

  1. 创建environment并加载System.properties()及System.getenv()到environment中,

obtainFreshBeanFactory()

创建BeanFactory

  1. 创建一个DefaultListableBeanFactory
  2. 初始化所有的BeanDefine,XmlBeanDefinitionReader来读取所有Bean的定义,存储在DefaultListableBeanFactory的beanDefinitionMap里面

prepareBeanFactory()

为Bean工厂做准备

  1. 这里比较重要的就是整个了两个特殊的BeanPostProcessor
    1) ApplicationContextAwareProcessor
    这个Processor用于执行Aware接口,如果我们写的Bean实现了如下Aware接口,将会执行该Aware接口的对应方法:
            EnvironmentAware
            EmbeddedValueResolverAware
            ResourceLoaderAware
            ApplicationEventPublisherAware
            MessageSourceAware
            ApplicationContextAware
    2) ApplicationListenerDetector
    这个Processor是用于收集我们自己写的监听器,只要我们的Bean实现了ApplicationListener监听器,那么就会在初始化Bean期间调用postProcessMergedBeanDefinition方法时被收集到这个Bean中,在调用postProcessAfterInitialization注册为Spring的监听器。

postProcessBeanFactory(beanFactory)

扩展点,子类可以重写该方法,完成一些需要在BeanFactory创建后执行的操作。

invokeBeanFactoryPostProcessors(beanFactory)

执行上一步的扩展

registerBeanPostProcessors(beanFactory);

注册上所有的BeanPostProcessors,所有BeanPostProcessor类型的Bean会在此时完成实例化(通过getBean()方法)

initMessageSource()

国际化的,没看过

initApplicationEventMulticaster()

初始化事件广播器,当事件发布器发布事件时,会调用这个广播器来广播事件。
广播器默认实现是SimpleApplicationEventMulticaster,这个监听器支持设置一个线程池来做异步处理。
我们还可以设置errorHandler来统一处理所有监听事件的异常。前提是我们要自己定义一个BeanId为applicationEventMulticaster的ApplicationEventMulticaster。

onRefresh()

扩展点,子类可以重写该方法,完成一些定制的功能

registerListeners()

注册监听器,我们写的监听器也会在这里加上,但是加的是名字,对象并不会在此处实例化,实例化是在上面说的ApplicationListenerDetector.postProcessAfterInitialization(…)方法中来在添加到ApplicationEventMulticaster中的,这里具体加个名字目前自己理解的话,是解决事件监听器scope不为单例时的应用。

finishBeanFactoryInitialization(beanFactory)

在实例化Bean的过程中,会按照顺序执行.,如下:

  1. resolveBeforeInstantiation会找到类型为InstantiationAwareBeanPostProcessor,且在Bean初始化前对Bean执行操作,可以在此处也返回代理(AOP就这么玩的),beanFactory的hasInstantiationAwareBeanPostProcessors这个属性决定值执不执行。
  2. 实例化 ----》 AbstractAutowireCapableBeanFactory.doCreateBean()
  3. populateBean注入属性
  4. initalizeBean方法调用扩展,顺序如下:
    1)如果Bean是BeanNameAware,BeanClassLoaderAware,BeanFactoryAware,会执行者几个的方法Aware的对应方法
    2)先执行所有BeanPostProcessor.postProcessBeforeInitialization()
    3) 反射调用init方法,如果Bean是InitializingBean,会先执行InitializingBean的afterPropertiesSet方法, 然后在执行自动以的init方法
    4)调用所有BeanPostProcessor.applyBeanPostProcessorsAfterInitialization()方法

@PostConstruct标记的方法,是在BeanPostProcessor.postProcessBeforeInitialization() 调用时执行,也就是有一个BeanPostProcessor用于处理标记了该注解的方法(InitDestroyAnnotationBeanPostProcessor),定时器等注解,原理也是一样的,在解析BeanDefinition时,会将这些注解都解析成BeanDefinition的一个属性

finishRefresh()

  1. 在所有Bean加载完毕后,在容器中找beanId为lifecycleProcessor的LifecycleProcessor,找到则用找到的,没有找到值创建一个默认的DefaultLifecycleProcessor,然后就会执行这个LifecycleProcessor的onRefresh方法。在DefaultLifecycleProcessor执行onRefresh方法时,会去容器中找SmartLifecycle类型的Bean,并执行SmartLifecycle.start()方法,可以在此处扩展整个BeanFactory创建及初始化完成后的操作。
  2. 发布一个ContextRefreshedEvent事件,SpringMVC就是基于这个事件扩展的
突破NER性能瓶颈:BERT与LLM协同的混合架构实践 性能卓越:在多个测试集上,F1分数比单一模型提升5-15%成本可控:相比纯LLM方案,成本降低60%以上易于落地:架构清晰,便于调试和优化这种"专才+通才"的组合思路可以扩展到其他NLP任务中,如关系抽取、事件提取、文本分类等。更精细的流水线优化多模型投票机制在线学习与自适应调整不追求单一模型的万能,而是通过精心设计的组合,让每个组件发挥其独特优势,最终实现系统性能的最优化。欢迎在评论区分享你在NER任务中的实践经验,或者对这个混合架构的改进建议! 阅读详情

相关推荐

别再用图片水印了!5种你可能不知道的文本隐写术实战

本文介绍了5种高效的文本隐写术,帮助创作者在不影响内容可读性的情况下嵌入版权信息。从零宽度字符到同形字替换,再到标点符号变形和行尾空格编码,这些技术为数字内容提供了轻量级版权保护方案,特别适用于社交媒体和电子合同等场景。

k8l9m0n的博客 225

[读书笔记]AbstractApplicationContext中refresh方法详解

Spring IoC容器对Bean定义资源的载入是从refresh()函数开始的,refresh()是一个模板方法,refresh()方法的作用是:在创建IoC容器前,如果已经有容器存在,则需要把已有的容器销毁和关闭,以保证在refresh之后使用的是新建立起来的IoC容器。refresh的作用类似于对IoC容器的重启,在新建立好的容器中对容器进行初始化,对Bean定义资源进行载入 FileSystemXmlApplicationContext通过调用其父类AbstractApplicationContex

小小默:进无止境 1万+

别再手动上传了!用宝塔面板的‘Let‘s Encrypt’免费SSL证书,3分钟自动续期

本文详细介绍了如何利用宝塔面板的‘Let‘s Encrypt’功能实现SSL证书的自动申请和续期,3分钟完成配置即可永久免费使用。通过对比不同SSL证书方案,突出Let's Encrypt的免费、自动续期和高安全性优势,特别适合个人博客和中小企业官网。

weixin_30415113的博客 150

spring中AbstractApplicationContext的refresh()

这个部分的源码看的次数不计其数了,每次看不同开源组件的调用过程中走到这里都有不同的收获。spring 中 AbstractApplicationContext 的 refresh() 是 spring 的核心,几乎所有的逻辑都在是这里间接被调用。如下源码为 spring boot 2.7.15 自带的 spring 5.3.29通过 WebApplicationType 判断是哪个环境判断逻辑如下。

zlpzlpzyd的专栏 536

基于 STM32 的智能水表流量计设计与实现 —— 数据采集与远程传输

本文设计的基于 STM32 的智能水表流量计通过霍尔传感器实现流量采集,结合 STM32 的处理能力完成数据计算、存储与远程传输,具备计量精准、功耗低、可远程监控等特点。未来可优化方向:引入低功耗模式延长电池寿命,增加水质检测模块实现多参数监测,提升水务管理智能化水平。

weixin_42300449的博客 1027

再不入坑就晚了,深度神经网络概念大整理,最简单的神经网络是什么样子?

再不入坑就晚了,深度神经网络概念大整理,最简单的神经网络是什么样子?

我是香菜 3万+

Spring源码-IOC之AbstractApplicationContext#refresh

refresh是接口ConfigurableApplicationContext的方法,定义:加载或刷新配置的持久层表示,可能是Java Config类、XML文件、properties文件或关系型数据库模式。接口ConfigurableApplicationContext的子类AbstractApplicationContext对refresh方法做了基本实现,方法体由一系列方法调用组成蓝色为准备环境;绿色为创建、初始化bean工厂,并用工厂实例化bean;黄色为上下文初始化一些特有的功能。

orixixi的博客 1241

2025华为OD 面试手撕代码真题【字符串至多删除一个字符,是否能构成回文串】

2025华为OD 面试手撕代码真题【字符串至多删除一个字符,是否能构成回文串】

MISAYAONE的博客 1705

Spring源码剖析之AbstractApplicationContext抽象类的refresh()方法

Spring源码剖析之AbstractApplicationContext抽象类的refresh()方法 - 简书 Spring中AbstractApplicationContext抽象类的refresh()方法是用来刷新Spring的应用上下文的。下面Spring的应用上下文我都叫作context @Override public void refresh() throws BeansException, IllegalStateException { synchroni

yygr的博客 663

【VisDrone数据集】YOLOX训练VisDrone数据集步骤与结果

YOLOX训练VisDrone数据集步骤与结果。

Gorgeous_wxd 2233

实战案例七:Claude Code 构建完整的 Web 应用

前面的案例大多是单一功能的演示,本章将展示如何使用 Claude Code 从零开始构建一个完整的 Web 应用,涵盖需求分析、架构设计、编码实现、测试部署的全流程。

gaoxiang_120的专栏 581

AbstractApplicationContext.refresh()方法

refresh() public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 准备好刷新上下文 prepareRefresh(); // 告诉子类刷新内部bean工厂 ConfigurableLis...

小何的博客 1067

运动想象 (MI) 分类学习系列 (19) : EEG-TransNet

本文提出了一种基于注意力机制的卷积神经网络(EEG-TransNet),用于运动想象脑电图(MI-EEG)解码。该方法创新性地通过平均池化和方差池化提取多模态时间信息,并结合自注意力模块捕获长期依赖关系。消融实验表明,方差池化比最大池化更有效(p<0.05),且注意力模块和卷积编码器对特征判别性至关重要。可视化分析验证了该方法能学习到更具判别性的紧凑特征。该工作为MI-EEG解码提供了新的多尺度时间信息融合视角,代码已开源。

走在深度学习前沿的小宋 358

【spring】AbstractApplicationContext 的refresh() 方法学习

的refresh()方法仍然是整个Spring应用程序上下文初始化的核心流程入口。大体上的刷新生命周期依然保持一致。refresh()方法的执行流程是一个复杂的过程,它涉及到多个方法的调用和多个步骤的执行。在实际开发中,我们通常不需要直接调用refresh()方法,而是通过调用类的子类的refresh()方法来刷新应用上下文。

一个写了10年bug的程序员日常笔记。 1389

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

spring AbstractApplicationContext refresh() 方法

这个方法很重要,是spring项目启动过程中都需要调用的核心方法。 看下源码: @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for...

一只小棉花的博客 1104

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Spring AbstractApplicationContext抽象类的refresh()方法--笔记

Spring中AbstractApplicationContext抽象类的refresh()方法是用来刷新Spring的应用上下文的。下面Spring的应用上下文我都叫作context @Override public void refresh() throws BeansException, IllegalStateException { sy...

dieyuanjiao9299的博客 193

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

spring源码AbstractApplicationContext的refresh()方法

主要是为了说明,如果之前存在bean工厂,销毁之前的bean工厂。

qq_42297616的博客 534

AbstractApplicationContext的refresh方法之invokeBeanFactoryPostProcessors

invokeBeanFactoryPostProcessors执行BeanFactory后置处理器,当然前提是你已经在容器中注册过此处理器了。 protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDeleg...

早起的鸟儿有虫吃的博客 252

【四】Spring源码分析之启动主流程---AbstractApplicationContext的refresh方法

入口: 在SpringBoot启动的时候,SpringApplication的run方法中 refreshContext(context); 里面最终调用的是AbstractApplicationContext类的refresh方法来刷新容器 源码: @Override public void refresh() throws BeansException, IllegalSta...

Sid小杰的博客 2643

理理Spring中一个bean的创建过程-------AbstractApplicationContext这个抽象类中的refresh()方法

public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh"); // Prepare this context for refreshing. prep

Apple_Andy的博客 270

AbstractApplicationContext的refresh方法之postProcessBeanFactory方法

postProcessBeanFactory后处理beanFactory。时机是在所有的beanDenifition加载完成之后,bean实例化之前执行。比如,在beanfactory加载完成所有的bean后,想修改其中某个bean的定义,或者对beanFactory做一些其他的配置,就可以用此方法。在系列文章中,可以实现ClassPathXmlApplicationContext类并重写post...

早起的鸟儿有虫吃的博客 316

试读Spring源码(一)Spring容器初始化AbstractApplicationContext的refresh方法

Spring容器的初始化是定义在AbstractApplicationContext的refresh方法中。首先是避免多线程同时初始化,先对初始化过程加锁。prepareRefresh方法,是容器初始化之前的准备,记录容器初始化的时间,并初始化一些参数。 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();...

c82525的博客 232

spring5.0.5初始化源码学习三部曲之三:AbstractApplicationContext.refresh()方法

本章是《spring初始化源码学习三部曲》系列的终章,重点是学习AbstractApplicationContext.refresh()方法; 我们先来回顾ClassPathXmlApplicationContext类的初始化过程如下代码: public ClassPathXmlApplicationContext(String[] paths, Class&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;?&amp;

海鸥飞翔~龙 426

spring4.1.8初始化源码学习三部曲之三:AbstractApplicationContext.refresh方法

本章是《spring4.1.8初始化源码学习三部曲》系列的终篇,重点是学习AbstractApplicationContext类的refresh()方法; 原文地址:https://blog.csdn.net/boling_cavalry/article/details/81045637 我们先回顾ClassPathXmlApplicationContext类的初始化过程如下代码: publ...

程序员欣宸的博客 7033
上一篇: HashMap源码分析(JDK1.8)
coder_zf
博客等级 码龄7年 0粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值