解析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;
    }
    原文作者:Spring Cloud
    原文地址: https://blog.csdn.net/qq_27104805/article/details/52245553
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞