1.4.Spring源码解析——获取Document

 经过验证模式准备的步骤就可以进行Document加载了,同样XmlBeanFactoryReader类对于文档读取并没有亲历亲为,而是委托给了DocumentLoader去执行,这里的DocumentLoader是个接口正真调用的时DefaultDocumentLoader。

    public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
            ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {
              //创建文档解析对象工厂类,设置校验模式和校验的格式
        DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
        if (logger.isDebugEnabled()) {
            logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]");
        }
              //准备对xml进行解析
        DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
        return builder.parse(inputSource);
    }
protected DocumentBuilderFactory createDocumentBuilderFactory(int validationMode, boolean namespaceAware)
            throws ParserConfigurationException {

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(namespaceAware);

        if (validationMode != XmlValidationModeDetector.VALIDATION_NONE) {
            factory.setValidating(true);

            if (validationMode == XmlValidationModeDetector.VALIDATION_XSD) {
                // Enforce namespace aware for XSD...
                factory.setNamespaceAware(true);
                try {
                    factory.setAttribute(SCHEMA_LANGUAGE_ATTRIBUTE, XSD_SCHEMA_LANGUAGE);
                }
                catch (IllegalArgumentException ex) {
                    ParserConfigurationException pcex = new ParserConfigurationException(
                            "Unable to validate using XSD: Your JAXP provider [" + factory +
                            "] does not support XML Schema. Are you running on Java 1.4 with Apache Crimson? " +
                            "Upgrade to Apache Xerces (or Java 1.5) for full XSD support.");
                    pcex.initCause(ex);
                    throw pcex;
                }
            }
        }

        return factory;
    }

其中的参数entityResolver是通过调用XmlBeanDefinitionReader中方法getEntityResolver()传入的

protected EntityResolver getEntityResolver() {
             //一开始的时候entityResolver 为空
        if (this.entityResolver == null) {
            // Determine default EntityResolver to use.  
           //再XmlBeanDefinitionReader的父类AbstractBeanDefinitionReader中定义了resourceLoader为ResourceLoader
            ResourceLoader resourceLoader = getResourceLoader();
            if (resourceLoader != null) {
                this.entityResolver = new ResourceEntityResolver(resourceLoader);
            }
            else {
                this.entityResolver = new DelegatingEntityResolver(getBeanClassLoader());
            }
        }
        return this.entityResolver;
    }

      //其中的getResourceLoader方法
    public ResourceLoader getResourceLoader() {
 //找个resourceLoader再AbstractBeanDefinitionReader中定义
        return this.resourceLoader;
    }

    //查看AbstractBeanDefinitionReader类的初始化方法,
  protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        this.registry = registry;
        // Determine ResourceLoader to use.
        if (this.registry instanceof ResourceLoader) {
            this.resourceLoader = (ResourceLoader) this.registry;
        }
        else {
            this.resourceLoader = new PathMatchingResourcePatternResolver();
        }

        // Inherit Environment if possible
        if (this.registry instanceof EnvironmentCapable) {
            this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
        }
        else {
            this.environment = new StandardEnvironment();
        }
    } 
    //在XmlBeanFactory会初始化XmlBeanDefinitionReader,而XmlBeanDefinitionReader继承了AbstractBeanDefinitionReader,所以在初始化XmlBeanFactory的时候就已经吧registry传入了,这里的register为XmlBeanFactory所以后面选择的resourceLoader为PathMatchingResourcePatternResolver对象
  public class XmlBeanFactory extends DefaultListableBeanFactory {
    private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
    ...
}
    //PathMatchingResourcePatternResolver的初始化方法
    public PathMatchingResourcePatternResolver() {
  //这里的resourceLoader为默认的  
        this.resourceLoader = new DefaultResourceLoader();
    }

1.EntityResolver用法(接口)
 官网的解释是:如果SAX应用程序需要实现自定义处理外部实体,则必须实现此接口并使用setEntityResolver()方法向SAX驱动器注册一个实例。也就是说,对于解析一个XML,SAX首先读取该XML文档的声明,根据声明去寻找相应的DTD定义,以便对文档进行一个验证。
 默认的寻找规则,即通过网络(现实上就是声明的DTD的URI地址)来下载相应的DTD声明,并进行认证。
 EntityResolver的作用是项目本身就可以提供一个如何寻找DTD声明的方法,即有程序来实现寻找DTD声明的过程,比如我们将DTD温江放到项目中某处,在是现实直接将此文档读取并返回给SAX即可。
 Spring中通过setEntityResolver()方法对EntityResolver的获取,,Spring中使用DelegatingEntityResolver类为EntityResolver的实现类,resolveEntity实现方法如下

public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
        if (systemId != null) {
            if (systemId.endsWith(DTD_SUFFIX)) {
                //todo 如果DTD文件那么是从这里解析
                return this.dtdResolver.resolveEntity(publicId, systemId);
            }
            else if (systemId.endsWith(XSD_SUFFIX)) {
                //todo 通过调用META—INF/Spring.schemas解析
                return this.schemaResolver.resolveEntity(publicId, systemId);
            }
        }
        return null;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值