Spring容器基础 —— BeanFactory 加载 Bean

本文对 Bean 容器的加载过程进行分析。首先我们看一个简单的例子。

// MyTestBean.java
public class MyTestBean {
	private String testStr = "testStr";

	public String getTestStr() {
		return testStr;
	}

	public void setTestStr(String testStr) {
		this.testStr = testStr;
	}
}

// BeanFactoryTest.java
public class BeanFactoryTest {

	@Test
	public void testSimpleLoad() {
		BeanFactory factory = new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));
		MyTestBean bean = (MyTestBean) factory.getBean("myTestBean");
		System.out.println(bean.getTestStr());
		assertEquals("testStr", bean.getTestStr());
	}

}
<!-- beanFactoryTest.xml -->
<?xml version="1.0" encoding="utf-8" ?>

<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans
				http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">

	<bean id="myTestBean" class="org.springframework.mytest.MyTestBean"/>

</beans>

这是一个简单的例子,里面的具体内容可以分为以下几个部分说明。

1、对 XmlBeanFactory 的初始化

BeanFactoryTest ClassPathResource XmlBeanFactory XmlBeanDefinitionReader new ClassPathResource("beanFactoryTest.xml") 1 resource: Resource 2 new XmlBeanFactory(resource) 3 loadBeanDefinitions(resource) 4 loadBeanDefinitionNum 5 new XmlBeanFactory(resource) 6 BeanFactoryTest ClassPathResource XmlBeanFactory XmlBeanDefinitionReader

通过 ClassPathResource 提供 xml 资源,在初始化 XmlBeanFactory 的同时解析 xml 文件中的内容。

2、准备资源文件并注册Bean

XmlBeanFactory XmlBeanDefinitionReader EncodedResource Resource InputResource loadBeanDefinitions(resource) 1 new EncodedResource(resource) 2 encodedResource 3 loadBeanDefinitions(new EncodedResource(resource)) 4 getResource() 5 resource 6 getInputStream() 7 inputStream 8 new InputSource(inputStream) 9 inputSource 10 doLoadBeanDefinitions(inputSource, encodedResource.getResource()) 11 loadBeanDefinitionNum 12 XmlBeanFactory XmlBeanDefinitionReader EncodedResource Resource InputResource
  1. 首先封装资源文件,将参数 Resource 通过 EncodedResource 进行封装。
  2. 再从 Resource 中获取 InputStream 并转换为 InputSource
  3. 最后执行注册,其中核心有三点:获取XML文件的验证格式;加载XML文件获取Document;根据Document注册Bean。

获取XML文件的验证格式

XML 文件有两种类型:DTD 和 XSD 两种。Spring 通过判断 XML 文件是否有 DOCTYPE,如果有那就是 DTD,否则是 XSD。

获取Document

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

该函数完成了 Document 的加载。通过通用套路 SAX 解析 XML 文档。首先创建 DocumentBuilderFactory,再通过 DocumentBuilderFactory 创建 DocumentBuilder,进而解析 inputSource 来返回 Document 对象。

这里需要解释一下 EntityResolver 的作用。
通常来说,都是通过 XML 中定义的 DTD 或者 XSD 声明来下载对应的文件来处理 XML。但是这样会有可能导致下载不到从而解析失败。EntityResover 就是提供一个如何寻找声明的方法,可以允许程序在本地寻找声明文件。

解析及注册 BeanDefinitions

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
		// 实例化 DefaultBeanDefinitionDocumentReader 
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		// 记录统计前 BeanDefinition 加载个数
		int countBefore = getRegistry().getBeanDefinitionCount();
		// 加载及注册 Bean
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}

registerBeanDefinitions 函数完成了实际的注册工作。底层主要完成了对 beans 标签内所有 bean 的解析。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值