码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • spring框架源码十六、BeanDefinition加载注册子流程


    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)
        • 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);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    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)

    获取资源加载器、将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);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

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

    开始注册BeanDefinition。

    step8、XmlBeanDefinitionReader#registerBeanDefinitions

    创建BeanDefinitionDocumentReader、注册BeanDefinitions

    在这里插入图片描述

    step9、DefaultBeanDefinitionDocumentReader#registerBeanDefinitions

    在这里插入图片描述

    step10、DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions

    解析Document

    在这里插入图片描述

    step11、DefaultBeanDefinitionDocumentReader#parseBeanDefinitions

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

    在这里插入图片描述

    step12、DefaultBeanDefinitionDocumentReader#parseDefaultElement

    解析标签

    在这里插入图片描述

    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));
    		}
    	}
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    step14、BeanDefinitionReaderUtils#registerBeanDefinition

    注册BeanDefinition

    在这里插入图片描述

    step15、DefaultListableBeanFactory#registerBeanDefinition

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

    在这里插入图片描述

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

  • 相关阅读:
    Pytorch环境配置——从零开始(不需要anaconda)
    支持国密ssl的curl编译和测试验证(上)
    【ATT&CK】MITRE Caldera-emu插件
    十大排序算法详解-上篇:比较排序算法【python 动态图解】
    微软云计算[3]之Windows Azure AppFabric
    java内存分页工具类
    【Rust日报】2022-08-07 专注于开发人员生产力的 R3BL TUI 库和应用程序
    【STM32】入门(五):串口TTL、RS232、RS485
    Pinia的使用
    初阶指针(1)
  • 原文地址:https://blog.csdn.net/qq_35549286/article/details/127912656
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号