BeanDefinition载入分析-中篇

前面说到的是XmlBeanDefinitionReader阅读器中的父类对loadBenaDefinition的规范

public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
    //就是说明resource资源的定位必须为非空的
        Assert.notNull(resources, "Resource array must not be null");
        int count = 0;
        Resource[] var3 = resources;
        int var4 = resources.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            Resource resource = var3[var5];
            count += this.loadBeanDefinitions((Resource)resource);
        }

        return count;
    }
//注意这个loadBeanDefinitions是一个抽象方法,它是没有实现的,具体的实现在其子类XmlBeanDefinitionReader中

在读取器中需要得到Resource,因为这个resource对象中封装了XML文件的I/O操作,所以阅读器需要的到Resource对象得到XMl中的文件对象
在的到Resource对象之后可以按照Spring的Bean定义规则对这个XML的文档树进行解析了
第二部分:利用BeanDefinitionParserDelegate来完成对文档树的解析工作,
下面的代码讲述的就是BeanDefinition的载入

//载入xml的Resource资源
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
        Assert.notNull(encodedResource, "EncodedResource must not be null");
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Loading XML bean definitions from " + encodedResource);
        }

        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 {
                //这里的到Xml的resource,并且得到Io中InoutStream对象
                InputStream inputStream = encodedResource.getResource().getInputStream();

                try {
                    InputSource inputSource = new InputSource(inputStream);
                    if (encodedResource.getEncoding() != null) {
                        inputSource.setEncoding(encodedResource.getEncoding());
                    }
                    
                    //记住doloadBeanDefinitons这个方法
                    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;
        }
    }

下面这个部分是对doLoadBeanDefinitions方法的解析
代码解析如下:

//具体的
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
        try {
            //这里有必要对它进行标识,是调用doLoadDocument来对resource进行调用,这个doLoadDopcument是指代DefaultLoader
            Document doc = this.doLoadDocument(inputSource, resource);
            //到这一步就时调用Spring中规范
            int count = this.registerBeanDefinitions(doc, resource);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Loaded " + count + " bean definitions from " + resource);
            }

            return count;
        } catch (BeanDefinitionStoreException var5) {
            throw var5;
        } catch (SAXParseException var6) {
            throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var6.getLineNumber() + " in XML document from " + resource + " is invalid", var6);
        } catch (SAXException var7) {
            throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var7);
        } catch (ParserConfigurationException var8) {
            throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var8);
        } catch (IOException var9) {
            throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var9);
        } catch (Throwable var10) {
            throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var10);
        }
    }

再下面的就是分析怎样将BeanFacotory进行转化成容器内部的数据结构的,也就是对registBeanDefinitions这个方法的分析了,具体的源码实现是在BeanDefinitionDocumentReader中完成的
实际的代码如下:

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    //得到BeanDefinitionDocumentReader来对XML的BeanDefinition进行分析
        BeanDefinitionDocumentReader documentReader =this.createBeanDefinitionDocumentReader();
    //记录注册之前的次数
        int countBefore = this.getRegistry().getBeanDefinitionCount();
        documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
        return this.getRegistry().getBeanDefinitionCount() - countBefore;
    }

是对上面的代码解析:BeanDefinition载入是分为两个部分的
1:调用xml的解析器得到document对象,这些document不是按照spring规则解析的
2:按照xml解析器解析过后的,就需要按照spring的Bean规则对其进行解析
具体的解析地方是在:documentReader中进行的(DefaultBeanDefinitionDoucmentReader)
3:然后调用BeanDefinition的处理,处理的结果被BeanDefintiionHolder的对象所持有
在这个BeanDefinitionHolder中存储的信息数据主要有Bean的名字,别名集合等
4:然后就是对BeanDefinition进行所谓的解析
主要是通过对Document文档树的内容进行解析来完成 -BeanDefintiionParserDelegate进行解析实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值