Análise do modelo de verificação da mola IOC

Escreva na frente

Neste trabalho, o artigo deu continuidade a partir da análise, como suplemento.

1: Função

A função da verificação é garantir a exatidão do arquivo xml.Somente quando o arquivo xml estiver completamente correto, as operações subsequentes, como o carregamento de definições de bean, podem continuar.

2: mecanismo de verificação xml

Os mecanismos de verificação de xml atuais incluem DTD (Document Type Definition) e XSD (Xml Schema Definition). O primeiro é anterior e o XSD é posterior, devido aos vários defeitos do DTD (como menos tipos de dados, escalabilidade fraca, xml não padrão formato, resultando na análise Difícil), foi eliminado, o XSD tornou-se o mainstream.

3: Processo de verificação

Para facilitar a depuração e, em seguida, cole o código de teste:

@Test
public void testBeanDefinitionLoad() {
    
    
    // 定义资源
    ClassPathResource classPathResource = new ClassPathResource("testbeandefinition.xml");
    // 定义IOC容器
    DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
    // 定义bean定义读取器
    XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
    // 通过bean定义读取器从资源中读取bean定义
    int i = xmlBeanDefinitionReader.loadBeanDefinitions(classPathResource);
    System.out.println("bean定义的个数是:" + i);
}

xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="testBeanDefinitionBean"
          class="yudaosourcecode.spring.TestBeanDefinitionBean"></bean>

    <bean id="testBeanDefinitionBean1"
          class="yudaosourcecode.spring.TestBeanDefinitionBean"></bean>
    <!-- 这里引入自己的话会发生org.springframework.beans.factory.BeanDefinitionStoreException异常 -->
    <!--<import resource="testbeandefinition.xml"/>-->
</beans>

A chamada final para o código:

org.springframework.beans.factory.xml.XmlBeanDefinitionReader#doLoadDocument
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
    
    
	return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
			getValidationModeForResource(resource), isNamespaceAware());
}

O método chama internamente o método para getValidationModeForResourceobter o modo de verificação. O código-fonte é o seguinte:

org.springframework.beans.factory.xml.XmlBeanDefinitionReader#getValidationModeForResource
protected int getValidationModeForResource(Resource resource) {
    
    
	// <2021-02-25 12:16> 获取设置的验证模式
	int validationModeToUse = getValidationMode();
	// 如果是设置的验证模式不是VALIDATION_AUTO,
	// private int validationMode = VALIDATION_AUTO;
	// public static final int VALIDATION_AUTO = XmlValidationModeDetector.VALIDATION_AUTO;
	// public static final int VALIDATION_AUTO = 1;
	// 则使用,否则继续
	if (validationModeToUse != VALIDATION_AUTO) {
    
    
		return validationModeToUse;
	}
	// <2021-02-25 12:21> 从资源中自动获取验证模式
	int detectedMode = detectValidationMode(resource);
	// 不是自动则使用自动获取的
	if (detectedMode != VALIDATION_AUTO) {
    
    
		return detectedMode;
	}
	// 手动也没有设置,自动也没有获取到,则默认XSD
	// public static final int VALIDATION_XSD = XmlValidationModeDetector.VALIDATION_XSD;
	// org.springframework.util.xml.XmlValidationModeDetector#VALIDATION_XSD
	// public static final int VALIDATION_XSD = 3;
	return VALIDATION_XSD;
}

<2021-02-25 12:16>O código-fonte é o seguinte:

org.springframework.beans.factory.xml.XmlBeanDefinitionReader#getValidationMode
public int getValidationMode() {
    
    
	// 默认值为自动验证模式
	// private int validationMode = VALIDATION_AUTO;
	return this.validationMode;
}

<2021-02-25 12:21>Obtenha o método de verificação do arquivo xml, o código-fonte é o seguinte:

org.springframework.beans.factory.xml.XmlBeanDefinitionReader#detectValidationMode
protected int detectValidationMode(Resource resource) {
    
    
	// 不可读,抛出BeanDefinitionStoreException
	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) {
    
    
		...snip throw ex...
	}

	try {
    
    
		// <2021-02-25 14:40>这里为真正获取验证模式位置
		return this.validationModeDetector.detectValidationMode(inputStream);
	}
	catch (IOException ex) {
    
    
		...snip throw ex...
	}
}

<2021-02-25 14:40>Aqui é realmente obter a localização do modo de verificação.

3.1 : XmlValidationModeDetector

Este é um objeto independente sem subclasses e sem classes pai 当然排除java.lang.Object后. Esta parte explica o <2021-02-25 14:40>código, o código-fonte é o seguinte:

public int detectValidationMode(InputStream inputStream) throws IOException {
    
    
	// Peek into the file to look for DOCTYPE.
	BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
	try {
    
    
		// 默认是dtd
		boolean isDtdValidated = false;
		String content;
		// 循环每一行进行判断
		while ((content = reader.readLine()) != null) {
    
    
			// 处理注释
			content = consumeCommentTokens(content);
			// 如果被注释包裹或者是没有内容,则continue
			if (this.inComment || !StringUtils.hasText(content)) {
    
    
				continue;
			}
			// 如果是有DOCTYPE关键字,则认为是dtd,这里一般为false
			// 如下就是包含DOCTYPE的情况
			// <?xml version="1.0" encoding="UTF-8"?>
			// <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
			if (hasDoctype(content)) {
    
    
				isDtdValidated = true;
				break;
			}
			// 如果是以<开头,并且紧接着的是一个字母,则为true,因为不是我们需要的,而是正常的定义内容,如<bean...
			if (hasOpeningTag(content)) {
    
    
				// End of meaningful data...
				break;
			}
		}
		// 如果是isDtdValidated为true则返回dtd,否则xsd
		return (isDtdValidated ? VALIDATION_DTD : VALIDATION_XSD);
	}
	catch (CharConversionException ex) {
    
    
		// 发生异常则返回自动验证模式
		return VALIDATION_AUTO;
	}
	finally {
    
    
		reader.close();
	}
}

Então, por aqui , veja como o recurso é carregado como um objeto de documento Documento.

Acho que você gosta

Origin blog.csdn.net/wang0907/article/details/114025933
Recomendado
Clasificación