解析Spring源码(5)--this.documentLoader.loadDocument

承接上一篇。。。

    /**
     * private DocumentLoader documentLoader = new DefaultDocumentLoader();
     * 对象解析文件流
     * 
     * Actually load the specified document using the configured DocumentLoader.
     * @param inputSource the SAX InputSource to read from
     * @param resource the resource descriptor for the XML file
     * @return the DOM Document
     * @throws Exception when thrown from the DocumentLoader
     * @see #setDocumentLoader
     * @see DocumentLoader#loadDocument
     */
    protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
        return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
                getValidationModeForResource(resource), isNamespaceAware());
    }

这个调用,使用的参数很多!让我们一一进行分析。。。

  • getEntityResolver()
    /**
     *将 ResourceLoader resourceLoader 对象封装,返回
     * Return the EntityResolver to use, building a default resolver
     * if none specified.
     */
    protected EntityResolver getEntityResolver() {
        if (this.entityResolver == null) {
            // Determine default EntityResolver to use.创建reader对象时进行过初始化,获取到封装类加载器的对象
            ResourceLoader resourceLoader = getResourceLoader();
            if (resourceLoader != null) {
                //又把resourceLoader封装了,赋值entityResolver
                this.entityResolver = new ResourceEntityResolver(resourceLoader);
            }
            else {
                this.entityResolver = new DelegatingEntityResolver(getBeanClassLoader());
            }
        }
        return this.entityResolver;
    }

上面同时也调用了很多方法,先不一一介绍以免混乱

  • getValidationModeForResource(resource)
        /**
     * 对xml文件的验证模式dtd,xsd判断选择
     * Gets the validation mode for the specified {@link Resource}. If no explicit
     * validation mode has been configured then the validation mode is
     * {@link #detectValidationMode detected}.
     * <p>Override this method if you would like full control over the validation
     * mode, even when something other than {@link #VALIDATION_AUTO} was set.
     */
    protected int getValidationModeForResource(Resource resource) {
        /**private int validationMode = VALIDATION_AUTO;
         *public static final int VALIDATION_AUTO = 1;
         *public static final int VALIDATION_AUTO = XmlValidationModeDetector.VALIDATION_AUTO;
         */
        int validationModeToUse = getValidationMode();//1
        if (validationModeToUse != VALIDATION_AUTO) {
            return validationModeToUse;
        }
        int detectedMode = detectValidationMode(resource);//3
        if (detectedMode != VALIDATION_AUTO) {
            return detectedMode;
        }
        // Hmm, we didn't get a clear indication... Let's assume XSD,
        // since apparently no DTD declaration has been found up until
        // detection stopped (before finding the document's root tag).
        return VALIDATION_XSD;
    }

    /**
     * Detects which kind of validation to perform on the XML file identified
     * by the supplied {@link Resource}. If the file has a {@code DOCTYPE}
     * definition then DTD validation is used otherwise XSD validation is assumed.
     * <p>Override this method if you would like to customize resolution
     * of the {@link #VALIDATION_AUTO} mode.
     */
    protected int detectValidationMode(Resource resource) {
        if (resource.isOpen()) {
            throw new BeanDefinitionStoreException(
                    "Passed-in Resource [" + resource + "] contains an open stream: " +
                    "cannot determine validation mode automatically. Either pass in a Resource " +
                    "that is able to create fresh streams, or explicitly specify the validationMode " +
                    "on your XmlBeanDefinitionReader instance.");
        }

        InputStream inputStream;
        try {
            inputStream = resource.getInputStream();//输入流
        }
        catch (IOException ex) {
            throw new BeanDefinitionStoreException(
                    "Unable to determine validation mode for [" + resource + "]: cannot open InputStream. " +
                    "Did you attempt to load directly from a SAX InputSource without specifying the " +
                    "validationMode on your XmlBeanDefinitionReader instance?", ex);
        }

        try {
            //  private final XmlValidationModeDetector validationModeDetector = new XmlValidationModeDetector();
            return this.validationModeDetector.detectValidationMode(inputStream);//3
        }
        catch (IOException ex) {
            throw new BeanDefinitionStoreException("Unable to determine validation mode for [" +
                    resource + "]: an error occurred whilst reading from the InputStream.", ex);
        }
    }
    /**
     * 返回验证模式,此为3,xsd
     * Detect the validation mode for the XML document in the supplied {@link InputStream}.
     * Note that the supplied {@link InputStream} is closed by this method before returning.
     * @param inputStream the InputStream to parse
     * @throws IOException in case of I/O failure
     * @see #VALIDATION_DTD
     * @see #VALIDATION_XSD
     */
    public int detectValidationMode(InputStream inputStream) throws IOException {
        // Peek into the file to look for DOCTYPE.
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        try {
            boolean isDtdValidated = false;
            String content;
            //读取xml文件
            while ((content = reader.readLine()) != null) {
                content = consumeCommentTokens(content);//不变
                if (this.inComment || !StringUtils.hasText(content)) {//inComment==false,没读取到内容跳回循环
                    continue;
                }
                if (hasDoctype(content)) {//是否包含Doctype
                    isDtdValidated = true;
                    break;
                }
                if (hasOpeningTag(content)) {
                    // End of meaningful data...
                    break;
                }
            }
            return (isDtdValidated ? VALIDATION_DTD : VALIDATION_XSD);//返回3
        }
        catch (CharConversionException ex) {
            // Choked on some character encoding...
            // Leave the decision up to the caller.
            return VALIDATION_AUTO;
        }
        finally {
            reader.close();
        }
    }
  • isNamespaceAware()
    private boolean namespaceAware = false;
    public boolean isNamespaceAware() {
        return this.namespaceAware;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值