承接上一篇。。。
/** * 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;
}