Spring源码解析02:Spring IOC容器之XmlBeanFactory启动流程分析和源码解析 (2)

好了,当你心里对这个流程有个大概的样子之后,这里就可以继续走下去。建议还是很模糊的同学自重,避免走火入魔想对我人身攻击的。下面就每个方法重要的点一一解析,严格按照方法的执行先后顺序来说明。

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;
        }
    ...
}

知识点:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjwff.html