好了,当你心里对这个流程有个大概的样子之后,这里就可以继续走下去。建议还是很模糊的同学自重,避免走火入魔想对我人身攻击的。下面就每个方法重要的点一一解析,严格按照方法的执行先后顺序来说明。
1.1 XmlBeanFactory(Resource resource)功能概述: XmlBeanFactory的构造方法,整个容器启动的入口,完成bean工厂的实例化和BeanDefinition加载(解析和注册)。
/*** XmlBeanFactory
**/
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
// 加载(解析注册)BeanDefinition
this.reader.loadBeanDefinitions(resource);
}
知识点:
Resource:Resource接口是Spring资源访问策略的抽象,,而具体的资源访问方式由其实现类完成,如类路径资源(ClassPathResource)、文件(FileSystemResource)、URL资源(UrlResource)、InputStream资源(InputStreamResource)、Byte数组(ByteArrayResource),根据不同的类型的资源使用对应的访问策略,明明白白的策略模式。
2.1 loadBeanDefinitions(Resource resource)功能概述: 上面根据ClassPathResource资源访问策略拿到了资源Resource,这里将Resource进行特定的编码处理,然后将编码后的Resource转换成SAX解析XML文件所需要的输入源InputSource。
/*** XmlBeanDefinitionReader
**/
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
// 把从XML文件读取的Resource资源进行编码处理
return loadBeanDefinitions(new EncodedResource(resource));
}
/**
* XmlBeanDefinitionReader
**/
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
...
// 完成resource->inputStream->inputSource转换,使用SAX方式接收输入源InputSource解析XML
try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
// 执行加载BeanDefinition
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
...
}
知识点:
XML解析两种方式:SAX(Simple API for XML)和DOM(Document Object Model),区别在于SAX按照顺序逐行读取,查找到符合条件即停止,只能读不能修改,适合解析大型XML;DOM则是一次性读取到内存建立树状结构,占用内存,不仅能读还能修改XML。Spring采用的SAX方式来解析XML。
2.2 doLoadBeanDefinitions(InputSource inputSource, Resource resource)功能概述: 获取DOM Document对象,XmlBeanDefinitionReader本身没有对文档读取的能力,而是委托给DocumentLoader的实现类DefaultDocumentLoader去读取输入源InputResource从而得到Document对象。获得Document对象后,接下来就是BeanDefinition的解析和注册。
/*** XmlBeanDefinitionReader
**/
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
...
try {
// inputSource->DOM Document
Document doc = doLoadDocument(inputSource, resource);
int count = registerBeanDefinitions(doc, resource);
return count;
}
...
}
知识点: