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文档扫描仪