spring框架源码十六、BeanDefinition加载注册子流程

news2024/11/25 11:37:36

BeanDefinition加载注册子流程

  • 时序图
    • 时序图1
      • step0、new ClassPathXmlApplicationContext
      • step1、ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String)
      • step2、ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String[], boolean, org.springframework.context.ApplicationContext)
      • step3、AbstractApplicationContext#refresh
      • step4、AbstractApplicationContext#obtainFreshBeanFactory
      • step5、AbstractRefreshableApplicationContext#refreshBeanFactory
      • step6、AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)
      • step7、AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)
    • 时序图2
      • step1、AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String...)
      • step2、AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String)
      • step3、AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String, java.util.Set<org.springframework.core.io.Resource>)
      • step4、AbstractBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource...)
      • step5、XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource)
      • step6、XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.support.EncodedResource)
      • step7、XmlBeanDefinitionReader#doLoadBeanDefinitions
      • step8、XmlBeanDefinitionReader#registerBeanDefinitions
      • step9、DefaultBeanDefinitionDocumentReader#registerBeanDefinitions
      • step10、DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions
      • step11、DefaultBeanDefinitionDocumentReader#parseBeanDefinitions
      • step12、DefaultBeanDefinitionDocumentReader#parseDefaultElement
      • step13、DefaultBeanDefinitionDocumentReader#processBeanDefinition
      • step14、BeanDefinitionReaderUtils#registerBeanDefinition
      • step15、DefaultListableBeanFactory#registerBeanDefinition

时序图

先上时序图,
这两张时序图加起来是完整的BeanDefinition加载注册子流程。

时序图1

在这里插入图片描述

step0、new ClassPathXmlApplicationContext

在这里插入图片描述

step1、ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String)

在这里插入图片描述

step2、ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String[], boolean, org.springframework.context.ApplicationContext)

在这里插入图片描述

step3、AbstractApplicationContext#refresh

在这里插入图片描述

step4、AbstractApplicationContext#obtainFreshBeanFactory

在这里插入图片描述

step5、AbstractRefreshableApplicationContext#refreshBeanFactory

开始加载应用中的BeanDefinitions

在这里插入图片描述

step6、AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)

创建xmlBeanDefinition读取器并设置上下文环境、加载BeanDefinitions

在这里插入图片描述

	/**
	 * Loads the bean definitions via an XmlBeanDefinitionReader.
	 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
	 * @see #initBeanDefinitionReader
	 * @see #loadBeanDefinitions
	 */
	@Override
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// 为给定的BeanFactory创建一个xmlBeanDefinition读取器
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// 给xmlBeanDefinition读取器设置上下文环境
		// Configure the bean definition reader with this context's
		// resource loading environment.
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// Allow a subclass to provide custom initialization of the reader,
		// then proceed with actually loading the bean definitions.
		initBeanDefinitionReader(beanDefinitionReader);
		// 加载BeanDefinitions
		loadBeanDefinitions(beanDefinitionReader);
	}

step7、AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)

从xml文件加载BeanDefinition的信息

在这里插入图片描述

时序图2

在这里插入图片描述

step1、AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String…)

若有多个配置文件,for循环加载

在这里插入图片描述

step2、AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String)

在这里插入图片描述

step3、AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String, java.util.Set<org.springframework.core.io.Resource>)

获取资源加载器、将xml配置文件转为Resource资源对象、从Resource加载BeanDefinitions

在这里插入图片描述

step4、AbstractBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource…)

若有多个Resource对象,for循环加载

在这里插入图片描述

step5、XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource)

在这里插入图片描述

step6、XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.support.EncodedResource)

从Resource对象中获取inputStream流

在这里插入图片描述

step7、XmlBeanDefinitionReader#doLoadBeanDefinitions

将inputStream流解析为Document对象、解析Document对象封装BeanDefinition对象并注册

在这里插入图片描述

	/**
	 * Actually load bean definitions from the specified XML file.
	 * @param inputSource the SAX InputSource to read from
	 * @param resource the resource descriptor for the XML file
	 * @return the number of bean definitions found
	 * @throws BeanDefinitionStoreException in case of loading or parsing errors
	 * @see #doLoadDocument
	 * @see #registerBeanDefinitions
	 */
	protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {

		try {
			// 读取xml文件,将xml中的bean定义信息保存到Document对象
			Document doc = doLoadDocument(inputSource, resource);
			// 解析Document对象,封装BeanDefinition并注册
			int count = registerBeanDefinitions(doc, resource);
			if (logger.isDebugEnabled()) {
				logger.debug("Loaded " + count + " bean definitions from " + resource);
			}
			return count;
		}
		catch (BeanDefinitionStoreException ex) {
			throw ex;
		}
		catch (SAXParseException ex) {
			throw new XmlBeanDefinitionStoreException(resource.getDescription(),
					"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
		}
		catch (SAXException ex) {
			throw new XmlBeanDefinitionStoreException(resource.getDescription(),
					"XML document from " + resource + " is invalid", ex);
		}
		catch (ParserConfigurationException ex) {
			throw new BeanDefinitionStoreException(resource.getDescription(),
					"Parser configuration exception parsing XML from " + resource, ex);
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(resource.getDescription(),
					"IOException parsing XML document from " + resource, ex);
		}
		catch (Throwable ex) {
			throw new BeanDefinitionStoreException(resource.getDescription(),
					"Unexpected exception parsing XML document from " + resource, ex);
		}
	}

至此,bean定义信息读取完成,

开始注册BeanDefinition。

step8、XmlBeanDefinitionReader#registerBeanDefinitions

创建BeanDefinitionDocumentReader、注册BeanDefinitions

在这里插入图片描述

step9、DefaultBeanDefinitionDocumentReader#registerBeanDefinitions

在这里插入图片描述

step10、DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions

解析Document

在这里插入图片描述

step11、DefaultBeanDefinitionDocumentReader#parseBeanDefinitions

解析默认标签元素、解析自定义标签元素

在这里插入图片描述

step12、DefaultBeanDefinitionDocumentReader#parseDefaultElement

解析</bean/>标签

在这里插入图片描述

step13、DefaultBeanDefinitionDocumentReader#processBeanDefinition

封装BeanDefinition

在这里插入图片描述

	/**
	 * Process the given bean element, parsing the bean definition
	 * and registering it with the registry.
	 */
	protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		// 解析bean元素为BeanDefinitionHolder
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// 完成BeanDefinition的注册
				// Register the final decorated instance.
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			// Send registration event.
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}
	

step14、BeanDefinitionReaderUtils#registerBeanDefinition

注册BeanDefinition

在这里插入图片描述

step15、DefaultListableBeanFactory#registerBeanDefinition

完成注册:this.beanDefinitionMap.put(beanName, beanDefinition);

在这里插入图片描述

到这儿,
完成了BeanDefinition的注册。

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

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

相关文章

初识类和对象

即使是初学者应该对类和对象也不算陌生吧&#xff0c;是不是因为老有些人动不动就&#xff1a;你知道伐&#xff0c;Java是一款面向对象的语言……阿巴阿巴……我的老师告诉我Java难的一部分就是如何把一个对象给抽象出来&#xff0c;那阿涛不才&#xff0c;今天就先来会一会这…

超市售货统计程序

代码price{"牛奶":5.5,"可乐":6.7,"饼干":10,"糖果":10} day1{"day":"11.23","牛奶":10,"可乐":10,"饼干":10,"糖果":10} day2{"day":"11.24",&quo…

机器学习笔记之条件随机场(六)学习任务介绍(Learning)

机器学习笔记之条件随机场——学习任务介绍引言回顾&#xff1a;条件随机场求解边缘概率分布场景设计前向后向算法关于条件随机场的学习任务关于模型参数λ\lambdaλ求解梯度梯度求解梯度的简化过程总结引言 上一节介绍了使用前向后向算法求解基于链式条件随机场中某隐状态的边…

MySQL—优化数据库

优化MySQL数据库是数据库管理员的必备技能&#xff0c;通过不同的优化方式达到提高MySQL数据库性能的目的。本节将介绍优化的基本知识。 MySQL数据库的用户和数据非常少的时候&#xff0c;很难判断一个MySQL数据库性能的好坏。只有当长时间运行&#xff0c;并且有大量用户进行…

GoogLenet网络详解

GoogLenet VGG在2014年由牛津大学著名研究组vGG (Visual Geometry Group)提出&#xff0c;斩获该年lmageNet竞赛中Localization Task (定位任务)第一名和 Classification Task (分类任务)第二名。Classification Task (分类任务)的第一名则是GoogleNet 。GoogleNet是Google研发…

vue-router 使用与原理分析,测试结果来啦

简介 Vue Router 是Vue.js的官方路由。与Vue.js核心深度集成&#xff0c;让用Vue.js构建单页应用&#xff08;SPA&#xff09;变得更加简单。 对于开发和维护管理后台类的前端项目&#xff0c;页面结构和组合可能非常复杂&#xff0c;所以正确的理解和使用Vue Router就显得尤为…

[附源码]SSM计算机毕业设计ssm新冠疫苗预约接种信息管理JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Spring事务管理

认识事务 可以把一系列&#xff08;多条sql语句&#xff09;要执行的操作称为事务&#xff0c;而事务管理就是管理这些操作要么完全执行&#xff0c;要么完全不执行&#xff08;很经典的一个例子是&#xff1a;A要给B转钱&#xff0c;首先A的钱减少了&#xff0c;但是突然的数…

EMQX数据流转MySQL踩坑日记:EMQX VER 4.2.3

总结&#xff1a; &#xff08;0&#xff09;数据库报错问题&#xff0c;详细参考这篇文档&#xff0c;链接&#xff0c;ln -s 源 目标 https://blog.csdn.net/weixin_42110159/article/details/118945136 &#xff08;1&#xff09;数据库建立数据&#xff0c;要注意大小写&am…

数字化开采|AIRIOT智慧矿山自动化生产解决方案

由于矿山地形复杂&#xff0c;生产自动化水平低&#xff0c;安全监管技术落后&#xff0c;事故频发等很多因素对煤矿开采技术提出了数据化、可视化、智能化的要求。通过目前的煤矿开采现状可以发现煤矿开采过程中&#xff0c;在生产、监管、巡检、安全、效率等方面还存在许多有…

图文详解Linux基础经典教程(08)——CentOS安装MySQL数据库

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 概述 之前&#xff0c;我们在CentOS中安装了JDK、Tomcat&#xff1b;接下来&#xff0c;我们在CentOS中采用YUM的方式安装MySQL5.6数据库。 安装前准备工作 在此&#xf…

面试常用算法归纳

最长子串、子序列 先说明下子串和子序列的问题&#xff1a;对于s “pwwkew"来说&#xff0c;其中一个子串为"wke”&#xff0c;而"pwke" 是一个子序列。 子序列&#xff1a;一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改…

基于Matlab通用视频处理系统的设计-含Matlab代码

⭕⭕ 目 录 ⭕⭕⏩ 一、引言⏩ 二、系统总体方案设计⏩ 2.1 方案设计⏩ 2.2 界面设计⏩ 三、实例分析⏩ 四、参考文献⏩ 五、Matlab程序获取⏩ 一、引言 随着信息技术的发展&#xff0c;基于视频图像中对感兴趣的目标提取&#xff0c;已经逐渐渗透到人们生活的方方面面&#x…

[附源码]SSM计算机毕业设计“拥抱爱心”公益网站管理系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

VMware Workstation 与 Device/Credential Guard 不兼容问题

系列文章目录 VMware Workstation 与 Device/Credential Guard 不兼容问题 VMware Workstation 与 Device/Credential Guard 不兼容问题系列文章目录一、原因二、解决办法2.1修改虚拟化安全设备为禁用2.2HV主机服务启动类型设置 为 “禁用”2.3关闭 Hyper-V 并且打开虚拟机平台…

CUDA By Example(六)——纹理内存

在本章中&#xff0c;我们将学习如何分配和使用纹理内存(Texture Memory)。和常量内存一样&#xff0c;纹理内存是另一种类型的只读内存&#xff0c;在特定的访问模式中&#xff0c;纹理内存同样能够提升性能并减少内存流量。虽然纹理内存最初是针对传统的图形处理应用程序而设…

Linux学习-43-挂载Linux系统外的文件mount和卸载文件系统umount命令用法

10.10 mount命令详解&#xff1a;挂载Linux系统外的文件 所有的硬件设备必须挂载之后才能使用&#xff08;新硬盘先格式化后创建分区&#xff0c;再对分区进行挂载&#xff09;&#xff0c;只不过&#xff0c;有些硬件设备&#xff08;比如硬盘分区&#xff09;在每次系统启动…

记录一次我虚拟机好不容易连上后的配置

有一说一&#xff0c;看到这个响应&#xff0c;人都麻了 在此我记录一下我检查了哪些&#xff0c;做了哪些 一、Windows本地服务 这一块&#xff0c;有一个算一个&#xff0c;没起的启动&#xff0c;启动的重启 二、VMware的虚拟网络编辑器设置 因为我这次成功用的是NAT模式&a…

图像分割 - 阈值处理 - 多阈值处理(OTSU)

目录 1. 多阈值处理介绍 2. 代码讲解 3. 完整代码 1. 多阈值处理介绍 之前介绍的都是全局单个阈值对图像的分割。固定阈值法&#xff0c;阈值是人工根据灰度直方图的波谷进行设置的。全局阈值法&#xff0c;根据不停的迭代两个区域间的平均灰度进行分割。OUST最大类间方差法…

centos7 环境安装 PM2 管理 node

前言&#xff1a; 由于最新的项目中用到的框架是 ssr 框架。 Vue使用的ssr是 nuxt.js&#xff0c;由于 nuxt.js 和普通的Vue项目不同&#xff0c;所以部署到Linux服务器的方式和普通的Vue项目是有区别的。 1、PM2 介绍 PM2 是一款非常优秀的 Node 进程管理工具&#xff0c;它…