spring源码解析-解析xml到IOC容器-spring加载文件对象

1、Resource: 接口 对资源的抽象,其实现类代表资源的访问策略

   继承InputStreamSource接口,提供获取输入流核心接口

InputStream getInputStream() throws IOException;
AbstractResource          抽象类
    FileSystemResource    文件路径资源类
    ByteArrayResource     二进制流资源类
    ClassPathResource     classpath路径资源类
    UrlResource           url资源类    

1.1、ClasspathResource:加载类路径下文件

// 1. 实例化对象
public ClassPathResource(String path, @Nullable ClassLoader classLoader) {
  Assert.notNull(path, "Path must not be null");
  String pathToUse = StringUtils.cleanPath(path);
  if (pathToUse.startsWith("/")) {
    pathToUse = pathToUse.substring(1);
  }
  this.path = pathToUse;
  this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
}
// 获取输入流对象
@Override
public InputStream getInputStream() throws IOException {
  InputStream is;
  if (this.clazz != null) {
    is = this.clazz.getResourceAsStream(this.path);
  }
  else if (this.classLoader != null) {
    is = this.classLoader.getResourceAsStream(this.path);
  }
  else {
    is = ClassLoader.getSystemResourceAsStream(this.path);
  }
  if (is == null) {
    throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");
  }
  return is;
}

2、XmlValidationModeDetector:XML验证模式检测器(DTD、XSD)

// XML文档类型判断
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;
    while ((content = reader.readLine()) != null) {
      content = consumeCommentTokens(content);
      if (this.inComment || !StringUtils.hasText(content)) {
        continue;
      }
      // DTD判断
      if (hasDoctype(content)) {
        isDtdValidated = true;
        break;
      }
      // XSD判断
      if (hasOpeningTag(content)) {
        break;
      }
    }
    return (isDtdValidated ? VALIDATION_DTD : VALIDATION_XSD);
  } catch (CharConversionException ex) {
    return VALIDATION_AUTO;
  } finally {
    reader.close();
  }
}            

3、DocumentLoader:文档加载器

// 核心接口,加载指定文档
Document loadDocument(InputSource inputSource, EntityResolver entityResolver, 
  ErrorHandler errorHandler,
int validationMode, boolean namespaceAware) throws Exception;

3.1、DefaultDocumentLoader:默认的文档加载器

// 实现加载文档
@Override
public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
  ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {
  // 创建文件构建器工厂
  DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
  // 创建文档构建器
  DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
  // 解析文档
  return builder.parse(inputSource);
}
  • 创建文件构造器工厂
// validationMode:校验模式(3:XSD)(2:DTD)
// namespaceAware:返回的工厂是否要提供对XML名称空间的支持
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) {
      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;
}
  • 创建文档构建器
// factory:文档构建器工厂(DocumentBuilderFactoryImpl)
// entityResolver:对象解析器(ResourceEntityResolver)
// errorHandler:解析错误处理器(SimpleSaxErrorHandler)
protected DocumentBuilder createDocumentBuilder(DocumentBuilderFactory factory,
            @Nullable EntityResolver entityResolver, @Nullable ErrorHandler errorHandler)
            throws ParserConfigurationException {
  DocumentBuilder docBuilder = factory.newDocumentBuilder();
  if (entityResolver != null) {
    docBuilder.setEntityResolver(entityResolver);
  }
  if (errorHandler != null) {
    docBuilder.setErrorHandler(errorHandler);
  }
  return docBuilder;
}
  •  解析文档
// is:XML文档输入流
public Document parse(InputSource is) throws SAXException, IOException {
  if (is == null) {
    throw new IllegalArgumentException(
      DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN,
      "jaxp-null-input-source", null));
    }
  if (fSchemaValidator != null) {
    if (fSchemaValidationManager != null) {
      fSchemaValidationManager.reset();
      fUnparsedEntityHandler.reset();
    }
    resetSchemaValidator();
  }
  domParser.parse(is);
  Document doc = domParser.getDocument();
  domParser.dropDocumentReferences();
  return doc;
}

 3.2、解析xml文件为Document  DOMParser(domParser.parse(is))

// 解析输入流
public void parse(InputSource inputSource) throws SAXException, IOException {
  try {
    XMLInputSource xmlInputSource = new XMLInputSource(inputSource.getPublicId(), inputSource.getSystemId(), null);
    xmlInputSource.setByteStream(inputSource.getByteStream());
    xmlInputSource.setCharacterStream(inputSource.getCharacterStream());
    xmlInputSource.setEncoding(inputSource.getEncoding());
    // 调用父类XMLParser的parse方法            
    parse(xmlInputSource);
  } catch (XMLParseException e) {
    Exception ex = e.getException();
    if (ex == null) {
      LocatorImpl locatorImpl = new LocatorImpl();
      locatorImpl.setPublicId(e.getPublicId());
      locatorImpl.setSystemId(e.getExpandedSystemId());
      locatorImpl.setLineNumber(e.getLineNumber());
      locatorImpl.setColumnNumber(e.getColumnNumber());
      throw new SAXParseException(e.getMessage(), locatorImpl);
    }
    if (ex instanceof SAXException) {
      throw (SAXException)ex;
    }
    if (ex instanceof IOException) {
      throw (IOException)ex;
    }
    throw new SAXException(ex);
  } catch (XNIException e) {
    Exception ex = e.getException();
    if (ex == null) {
      throw new SAXException(e.getMessage());
    }
    if (ex instanceof SAXException) {
      throw (SAXException)ex;
    }
    if (ex instanceof IOException) {
      throw (IOException)ex;
    }
    throw new SAXException(ex);
  }
}
  • XMLParser (parse(XMLImputSource))
// 解析输入流
public void parse(XMLInputSource inputSource) throws XNIException, IOException {
  if (securityManager == null) {
    securityManager = new XMLSecurityManager(true);
    fConfiguration.setProperty(Constants.SECURITY_MANAGER, securityManager);
  }
  if (securityPropertyManager == null) {
    securityPropertyManager = new XMLSecurityPropertyManager();
    fConfiguration.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager);
  }
  reset();
  // 调用XML11Configuration的parse(XMLInputSource)方法
  fConfiguration.parse(inputSource);
}
  • XML11Configuration (parse(XMLInputSource))
// 解析输入流
public void parse(XMLInputSource source) throws XNIException, IOException {
  if (fParseInProgress) {
    throw new XNIException("FWK005 parse may not be called while parsing.");
  }
  fParseInProgress = true;
  try {
    setInputSource(source);
    // 调用本类的parse(boolean)方法
    parse(true);
  } catch (XNIException ex) {
    if (PRINT_EXCEPTION_STACK_TRACE)
      ex.printStackTrace();
    throw ex;
  } catch (IOException ex) {
    if (PRINT_EXCEPTION_STACK_TRACE)
      ex.printStackTrace();
    throw ex;
  } catch (RuntimeException ex) {
    if (PRINT_EXCEPTION_STACK_TRACE)
      ex.printStackTrace();
    throw ex;
  } catch (Exception ex) {
    if (PRINT_EXCEPTION_STACK_TRACE)
      ex.printStackTrace();
    throw new XNIException(ex);
  } finally {
    fParseInProgress = false;
    this.cleanup();
  }
}
// 解析
public boolean parse(boolean complete) throws XNIException, IOException {
  if (fInputSource != null) {
    try {
      fValidationManager.reset();
      fVersionDetector.reset(this);
      fConfigUpdated = true;
      resetCommon();
      short version = fVersionDetector.determineDocVersion(fInputSource);
      if (version == Constants.XML_VERSION_1_1) {
        initXML11Components();
        configureXML11Pipeline();
        resetXML11();
      } else {
        configurePipeline();
        reset();
      }
      fConfigUpdated = false;
      fVersionDetector.startDocumentParsing((XMLEntityHandler) fCurrentScanner, version);
      fInputSource = null;
    } catch (XNIException ex) {
      if (PRINT_EXCEPTION_STACK_TRACE)
        ex.printStackTrace();
      throw ex;
    } catch (IOException ex) {
      if (PRINT_EXCEPTION_STACK_TRACE)
        ex.printStackTrace();
      throw ex;
    } catch (RuntimeException ex) {
      if (PRINT_EXCEPTION_STACK_TRACE)
        ex.printStackTrace();
      throw ex;
    } catch (Exception ex) {
      if (PRINT_EXCEPTION_STACK_TRACE)
        ex.printStackTrace();
      throw new XNIException(ex);
    }
  }

  try {
    // 调用XMLDocumentFragementScannerImpl的scanDocument(boolean)方法
    return fCurrentScanner.scanDocument(complete);
  } catch (XNIException ex) {
    if (PRINT_EXCEPTION_STACK_TRACE)
      ex.printStackTrace();
    throw ex;
  } catch (IOException ex) {
    if (PRINT_EXCEPTION_STACK_TRACE)
      ex.printStackTrace();
    throw ex;
  } catch (RuntimeException ex) {
    if (PRINT_EXCEPTION_STACK_TRACE)
      ex.printStackTrace();
    throw ex;
  } catch (Exception ex) {
    if (PRINT_EXCEPTION_STACK_TRACE)
      ex.printStackTrace();
    throw new XNIException(ex);
  }
}
  • XMLDocumentFragementScannerImpl (scanDocument(boolean)) XML文档片段扫描仪
// 循环解析结果处理
public boolean scanDocument(boolean complete) throws IOException, XNIException {
  fEntityManager.setEntityHandler(this);
  // 调用子类XMLNSDocumentScannerImpl的next()方法,执行具体解析
  int event = next();
  do {
    switch (event) {
      case XMLStreamConstants.START_DOCUMENT :
        break;
      case XMLStreamConstants.START_ELEMENT :
        break;
      case XMLStreamConstants.CHARACTERS :
        fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity);
        fDocumentHandler.characters(getCharacterData(),null);
        break;
      case XMLStreamConstants.SPACE:
        break;
      case XMLStreamConstants.ENTITY_REFERENCE :
        fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity);
            break;
      case XMLStreamConstants.PROCESSING_INSTRUCTION :
        fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity);
        fDocumentHandler.processingInstruction(getPITarget(),getPIData(),null);
        break;
      case XMLStreamConstants.COMMENT :
        fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity);
        fDocumentHandler.comment(getCharacterData(),null);
        break;
      case XMLStreamConstants.DTD :
        break;
      case XMLStreamConstants.CDATA:
        fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity);
        fDocumentHandler.startCDATA(null);
        fDocumentHandler.characters(getCharacterData(),null);
        fDocumentHandler.endCDATA(null);
        break;
      case XMLStreamConstants.NOTATION_DECLARATION :
        break;
      case XMLStreamConstants.ENTITY_DECLARATION :
        break;
      case XMLStreamConstants.NAMESPACE :
        break;
      case XMLStreamConstants.ATTRIBUTE :
        break;
      case XMLStreamConstants.END_ELEMENT :
        break;
      default :
        throw new InternalError("processing event: " + event);
    }
    // 调用子类XMLNSDocumentScannerImpl的next()方法,执行具体解析
    event = next();
  } while (event!=XMLStreamConstants.END_DOCUMENT && complete);
  if(event == XMLStreamConstants.END_DOCUMENT) {
    fDocumentHandler.endDocument(null);
    return false;
  }
  return true;
}
  • XMLNSDocumentScannerImpl (next())  XMLNS文档扫描仪
// 执行解析
public int next() throws IOException, XNIException {
  if((fScannerLastState == XMLEvent.END_ELEMENT) && fBindNamespaces){
    fScannerLastState = -1;
    fNamespaceContext.popContext();
  }
  // 调用父类XMLDocumentScannerImpl的next()方法
  return fScannerLastState = super.next();
}
  • XMLDocumentScannerImpl (next())   XML文档扫描仪
public int next() throws IOException, XNIException {
  // 调用XMLDocumentScannerImpl.XMLDeclDriver的next()方法
  return fDriver.next();
}
  • XMLDocumentScannerImpl.XMLDeclDriver (next())  XML Decl驱动程序
// 解析细节
public int next() throws IOException, XNIException {
  setScannerState(SCANNER_STATE_PROLOG);
  setDriver(fPrologDriver);
  try {
    if (fEntityScanner.skipString(xmlDecl)) {
      fMarkupDepth++;
      if (XMLChar.isName(fEntityScanner.peekChar())) {
        fStringBuffer.clear();
        fStringBuffer.append("xml");
        while (XMLChar.isName(fEntityScanner.peekChar())) {
          fStringBuffer.append((char)fEntityScanner.scanChar(null));
        }
        String target = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length);
        fContentBuffer.clear() ;
        scanPIData(target, fContentBuffer);
        fEntityManager.fCurrentEntity.mayReadChunks = true;
        return XMLEvent.PROCESSING_INSTRUCTION ;
      } else {
        scanXMLDeclOrTextDecl(false);
        fEntityManager.fCurrentEntity.mayReadChunks = true;
        return XMLEvent.START_DOCUMENT;
      }
    } else {
      fEntityManager.fCurrentEntity.mayReadChunks = true;
      return XMLEvent.START_DOCUMENT;
    }
  } catch (EOFException e) {
    reportFatalError("PrematureEOF", null);
    return -1;
  }
}

注:以上扫描器依赖关系

XMLDocumentFragmentScannerImpl:XML文档片段扫描器
    XMLDocumentScannerImpl:(子类)XML文档扫描仪
            XMLDeclDriver:(内部类)XML Decl驱动程序
        XMLNSDocumentScannerImpl:(子类) XMLNS文档扫描仪
posted @ 2020-06-18 17:42  张界  阅读(362)  评论(0编辑  收藏  举报