spring源码(三)--XmlBeanDefinitionReader

类继承层次图:
这里写图片描述

类名作用
BeanDefinitionReader定义资源文件读取并转换为BeanDefinition的功能
EnvironmentCapable定义了获取Environment的方法
AbstractBeanDefinitionReader对上面2个接口做了实现

XmlBeanDefinitionReader读取配置文件的大致流程

  1. 通过继承自 AbstractBeanDefinitionReader 的方法,使用ResourceLoader将资源文件路径转换为Resource
  2. 使用DocumentLoader对Resource文件进行转换,将Resource文件转换为Document文件
  3. 使用BeanDefinitionDocumentReader的实现类DefaultBeanDefinitionDocumentReader对Document进行解析,并使用BeanDefinitionParserDelegate对Element进行解析。

持有registry(其实就是beanfactory),reader解析配置文件之后,把bean注册到beanfactory中。


核心方法loadBeanDefinitions:

  1. 把编码源添加到currentResources 中
  2. 把inputStream转换为inputSource
  3. 使用DefaultDocumentLoader把 inputStream转换为Doucument
  4. 使用DefaultBeanDefinitionDocumentReader解析document,把bean注册到factory
Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
                    loadCount = this.loadBeanDefinitions(resources);
                    if(actualResources != null) {
                        Resource[] var6 = resources;
                        int var7 = resources.length;

                        for(int var8 = 0; var8 < var7; ++var8) {
                            Resource resource = var6[var8];
                            actualResources.add(resource);
                        }
                    }

                    return loadCount;

一连串的调用之后,会走到这里,resource其实就是spring的xml配置文件。

 public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
        Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
        if(currentResources == null) {
            currentResources = new HashSet(4);
            this.resourcesCurrentlyBeingLoaded.set(currentResources);
        }

        if(!((Set)currentResources).add(encodedResource)) {
            throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
        } else {
            int var5;
            try {
                InputStream inputStream = encodedResource.getResource().getInputStream();

                try {
                    InputSource inputSource = new InputSource(inputStream);
                    if(encodedResource.getEncoding() != null) {
                        inputSource.setEncoding(encodedResource.getEncoding());
                    }

                    var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
                } finally {
                    inputStream.close();
                }
            } catch (IOException var15) {
                throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15);
            } finally {
                ((Set)currentResources).remove(encodedResource);//目的是防止重复加载同一个配置文件
                if(((Set)currentResources).isEmpty()) {
                    this.resourcesCurrentlyBeingLoaded.remove();
                }

            }

            return var5;
        }
    }

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
            Document doc = this.doLoadDocument(inputSource, resource);
            return this.registerBeanDefinitions(doc, resource);
    }
    //这里的EntityResolver一般是ResourceEntityResolver(二般情况是DelegatingEntityResolver)
 protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
        return this.documentLoader.loadDocument(inputSource, this.getEntityResolver(), this.errorHandler, this.getValidationModeForResource(resource), this.isNamespaceAware());
    }
    //DefaultBeanDefinitionDocumentReader解析doc,DefaultBeanDefinitionDocumentReader在第十一篇
    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
        BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
        int countBefore = this.getRegistry().getBeanDefinitionCount();
        // Map<String, BeanDefinition> beanDefinitionMap的size大小,所以解析后的bean都放在这里
        documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
        return this.getRegistry().getBeanDefinitionCount() - countBefore;
    }

具体的解析过程转接到DefaultBeanDefinitionDocumentReader的doRegisterBeanDefinitions方法中。

关于EncodedResource,提供了reader对象,没有设置字符集和编码时,将使用默认的字符集解码。

public Reader getReader() throws IOException {
        return this.charset != null?new InputStreamReader(this.resource.getInputStream(), this.charset):(this.encoding != null?new InputStreamReader(this.resource.getInputStream(), this.encoding):new InputStreamReader(this.resource.getInputStream()));
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值