Spring-IOC之BeanFactory启动流程

1.流程概述

  IOC容器启动时会先将元数据(Configuration MetaData,即开发人员事先准备的XML或Annntation配置信息等)加载到容器环境中,然后再对这些元数据进行解析,将解析得到的BeanDefinition信息进一步编组成相应的BeanDefinitionHolder对象,最后再将编组对象进行注册,从而结束启动工作。
  以XML为例,BeanFactory启动时需要XmlBeanDefinitionReader通过loadBeanDefinitions方法将元数据资源加载到上下文环境中,以此作为容器的启动入口。

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
BeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new ClassPathResource("beans.xml"));

在这里插入图片描述

2.加载

public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
   

	private DocumentLoader documentLoader = new DefaultDocumentLoader();

	public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
   
		……
		InputStream inputStream = encodedResource.getResource().getInputStream();
		try {
   
			InputSource inputSource = new InputSource(inputStream);
			……
			return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
		}
		……
	}

	protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) 
		throws BeanDefinitionStoreException {
   
		
		try {
   
			Document doc = doLoadDocument(inputSource, resource);
			return registerBeanDefinitions(doc, resource);
	   	}
	   	// catch BeanDefinitionStoreException、SAXParseException等
	   	……
	}

	protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
   
		return this.documentLoader.loadDocument(inputSource, getEntityResolver(),
			this.errorHandler, getValidationModeForResource(resource), isNamespaceAware());
	}

	public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
   
		// DefaultBeanDefinitionDocumentReader
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		// 获取容器之前已注册在案的BeanDefinition数量
		int countBefore = getRegistry().getBeanDefinitionCount();
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		// 返回新注册成功的BeanDefinition数量
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}
}

  如上代码所示,XmlBeanDefinitionReader加载元数据时首先需要得到元数据的输入流(InputSource),其后再在doLoadBeanDefinitions方法中完成如下两项工作:

  1. 调用DefaultDocumentLoader的loadDocument方法,利用SAX技术将XML元数据解析成Document对象。
public class DefaultDocumentLoader implements DocumentLoader {
   

	public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
		ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {
   							
		
		DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
		DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
		return builder.parse(inputSource);
	}
}
  1. 调用XmlBeanDefinitionReader的registerBeanDefinitions方法完成后续的解析、编组和注册工作。

3.解析和编组

  需要注意的是,XmlBeanDefinitionReader在registerBeanDefinitions方法中完成注册之前,实际上还需要先将Document对象进一步解析成BeanDefinition。默认情况下,这项解析工作由DefaultBeanDefinitionDocumentReader来完成。

public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {
   
	
	public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
   
		this.readerContext = readerContext;
		logger.debug("Loading bean definitions");
		Element root = doc.getDocumentElement();
		doRegisterBeanDefinitions(root);
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值