spring ioc 容器加载过程 refresh() 方法详解

IOC 加载过程 从 new ClassPathXmlApplicationContext开始

ApplicationContext context = new 
ClassPathXmlApplicationContext("classpath:application.xml");

ClassPathXmlApplicationContext类构造方法

public ClassPathXmlApplicationContext(String[] configLocations,boolean refresh, @Nullable ApplicationContext parent) throws BeansException {super(parent);this.setConfigLocations(configLocations);if (refresh) {// 执行刷新操作this.refresh();}
}

核心类和接口

ApplicationContext接口 其实就是一个BeanFactory

作用: 加载配置文件中定义的 bean,并进行管理。

继承了ListableBeanFactory,这个ListableBeanFactory接口可以获取多个bean。
继承了HierarchicalBeanFactory接口,这个接口可以在应用这起多个BeanFactory,然后将多个BeanFactory设置父子关系。
getAutowireCapableBeanFactory() : 用来自动装配Bean

BeanDefinitionReader

配置文件解析器,如将配置文件中的 bean 信息解析成对应的 BeanDefinition 对象。

xml 文件解析使用是就是BeanDefinitionReader 实现类 XmlBeanDefinitionReader。

BeanFactoryPostProcessor

可以修改 Spring 上下文中 BeanDefinition 信息。

BeanFactory

是所有 Bean 容器的根接口,定义了 spring 容器基本方法。如使用 getBean(beanName,Class) 获取对象。

refresh() 详解

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//1:准备刷新上下文环境。prepareRefresh();//2:刷新并获取刷新后的 BeanFactory,将配置文件解析为BeanDefinition对象。ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//3:对 Bean 工厂进行填充属性。prepareBeanFactory(beanFactory);try {//4:beanFactory的后置处理器,空方法,具体由子类实现。// 使用设计模式中的模板方法,是一个钩子函数。postProcessBeanFactory(beanFactory);//5:实例化并调用所有注册的beanFactory后置处理器。invokeBeanFactoryPostProcessors(beanFactory);//6:加载 BeanPostProcessors。registerBeanPostProcessors(beanFactory);//7:国际化处理,为上下文实例化并注册一个MessageSource。initMessageSource();//8:初始化并注册一个事件广播器用来发布事件。initApplicationEventMulticaster();//9:空方法,由子类实现,使用设计模式中的模板方法,是一个钩子函数。onRefresh();//10:注册监听器,在所有注册的bean中查找Listener bean,注册到消息广播器中,即向监听器发布事件。registerListeners();//11:初始化所有的非懒加载的单实例bean(bean的生命周期实例化 属性注入 初始化 完成)finishBeanFactoryInitialization(beanFactory);//12:最后刷新容器 发布刷新事件。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()

准备刷新上下文环境。

obtainFreshBeanFactory()(重要)

刷新并获取刷新后的 BeanFactory,将配置文件解析为BeanDefinition对象。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {//刷新bean工厂()refreshBeanFactory();//返回之前容器准备工作的时候创建的的bean工厂也就是DefaultListableBeanFactory(很重要)ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (logger.isDebugEnabled()) {logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);}return beanFactory;
}
protected final void refreshBeanFactory() throws IllegalStateException {//由于BeanFactory只能刷新一次,多线程情况下可能导致线程安全问题,所有使用cas原子操作来保证if (!this.refreshed.compareAndSet(false, true)) {throw new IllegalStateException("GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");}//指定Bean工厂的序列化Idthis.beanFactory.setSerializationId(getId());
}
prepareBeanFactory()

对 Bean 工厂进行填充属性。

postProcessBeanFactory()

beanFactory的后置处理器,空方法,具体由子类实现。使用设计模式中的模板方法,是一个钩子函数。

invokeBeanFactoryPostProcessors()

实例化并调用所有注册的beanFactory后置处理器。

registerBeanPostProcessors()

加载 BeanPostProcessors。

initMessageSource()

国际化处理,为上下文实例化并注册一个MessageSource。

initApplicationEventMulticaster()

初始化并注册一个事件广播器用来发布事件。

onRefresh()

空方法,由子类实现,使用设计模式中的模板方法,是一个钩子函数。

registerListeners()

注册监听器,在所有注册的bean中查找Listener bean,注册到消息广播器中,即向监听器发布事件。

finishBeanFactoryInitialization()(重要)

初始化所有的非懒加载的单实例bean(bean的生命周期实例化 属性注入 初始化 完成)。

bean实例化 属性注入 初始化

关键方法

AbstractAutowireCapableBeanFactory类的doCreateBean方法
// 其中
createBeanInstance(beanName, mbd, args); // 实例化
populateBean(beanName, mbd, instanceWrapper); // 属性注入
initializeBean(beanName, exposedObject, mbd)  // 初始化
finishRefresh()

最后刷新容器发布刷新事件。

待续…

IOC容器步骤详解

面试详解

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

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

相关文章

Docker重启容器失败

Bug描述 [rootVM-12-15-centos ~]# docker restart ca1008fbdf25 Error response from daemon: Cannot restart container ca1008fbdf25: driver failed programming external connectivity on endpoint nginx_java (aded2fc7cbfa784b2e6a39e08d3ae2e7d00c13af88879a8fe7c5007…

飞腾E2000运行Zephyr操作系统

Phytium-Zephyr-SDK 1. 仓库介绍 1.1 本仓库特色 此项目是一个开源软件,专为物联网领域设计,基于Zephyr实时操作系统,针对Phytium系列CPU进行了专门的适配和应用开发。我们的目标是降低开发者的使用门槛,提供了部署文档和使用指…

Java毕设之学院党员管理系统的设计与实现

运行环境 环境说明: 开发语言:java 框架:springboot,vue JDK版本:JDK1.8 数据库:mysql5.7(推荐5.7,8.0也可以) 数据库工具:Navicat11 开发软件:idea/eclipse(推荐idea) Maven包:Maven3.3.9 系统实现 管理员功能实现 党员管理 管理员进入指定功能操作…

hadoop学习---基于hive的数仓搭建增量信息拉链表的实现

拉链表就是SCD2,它的优点是即满足了反应数据的历史状态,又能在最大程度上节省存储。 拉链表的实现需要在原始字段基础上增加两个新字段: start_time(表示该条记录的生命周期开始时间——周期快照时的状态)end_time(该条记录的生命周期结束时…

1.python爬虫爬取视频网站的视频可下载的源url

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、爬取的源网站二、实现代码总结 一、爬取的源网站 http://www.lzizy9.com/ 在这里以电影片栏下的动作片为例来爬取。 可以看到视频有多页,因此需要…

性能优化 | el-table中内嵌大量el-input控件导致渲染卡顿的问题

场景 项目中有一个应用场景,用户需要在表单中大量使用选择框以及输入框填写数据(每一行大概有三十几个输入框),当选择框与输入框达到一定数量的时候,页面会出现输入不连续、卡顿的现象,如下图:…

c++笔记——概述运算符重载——解析运算符重载的难点

前言:运算符重载是面向对象的一个重要的知识点。我们都知道内置类型可以进行一般的运算符的运算。但是如果是一个自定义类型, 这些运算符就无法使用了。那么为了解决这个问题, 我们的祖师爷就在c中添加了运算符重载的概念。 本篇主要通过实例的实现来讲述…

武汉星起航:策略升级,亚马逊平台销售额持续增长显实力

武汉星起航电子商务有限公司,一家致力于跨境电商领域的企业,于2023年10月30日在上海股权托管交易中心成功挂牌展示,这一里程碑事件标志着公司正式踏入资本市场,开启了新的发展篇章。公司董事长张振邦在接受【第一财经】采访时表示…

html5动漫风二次元网站博客引导页模板

html5动漫风二次元网站博客引导页模板 效果图部分源码领取源码下期更新预报 效果图 部分源码 <!DOCTYPE html> <!--孤独 --> <html xmlns"http://www.w3.org/1999/xhtml" lang"en"><head><meta charset"utf-8" /&g…

04-19 周四 GitHub CI 方案设计

04-19 周四 GitHub CI 方案设计 时间版本修改人描述2024年4月19日14:44:23V0.1宋全恒新建文档2024年4月19日17:22:57V1.0宋全恒完成部署拓扑结构的绘制和文档撰写 简介 需求 由于团队最近把代码托管在GitHub上&#xff0c;为解决推理、应用的自动化CI的需要&#xff0c;调研了…

考虑需求响应的微网优化调度模型【粒子群算法】【matlab】

目录 1 主要内容 1.1 模型约束条件 1.2 粒子群算法优化过程 2 部分代码 3 效果图 4 下载链接 1 主要内容 该模型构建了考虑需求响应的微电网优化调度模型&#xff0c;并采用粒子群算法&#xff08;PSO&#xff09;进行优化求解&#xff0c;模型主体有储能、风电、光伏、微…

Linux编译内核模块生成.KO驱动示例

现在的Linux内核十分庞大&#xff0c;驱动繁多&#xff0c;但是仍有一些是内核所不包含的&#xff0c;或者我们前期进行了内核裁剪&#xff0c;但后面又需要添加一些驱动&#xff0c;但是又不想重新烧录内核&#xff0c;这时候就可以使用内核模块功能&#xff0c;对内核驱动进行…