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

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

开始加载应用中的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的注册。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值