Spring IOC obtains Document object analysis based on xml file

write in front

This article continues to analyze on the basis of this article. This article analyzes how to obtain the verification mode. After obtaining the verification mode, the corresponding document object is generated from the xml file.

1: role

Information such as beans used to parse user configuration from it is a BeanDefinition data structure.

2: Test code

For the convenience of debugging, paste the test code:

@Test 
public  void  testBeanDefinitionLoad ( )  { 
    // Define resource 
    ClassPathResource classPathResource =  new  ClassPathResource ( "testbeandefinition.xml" ) ; 
    // Define IOC container 
    DefaultListableBeanFactory defaultListableBeanFactory =  new  DefaultListableBeanFactory ( ) ; 
    // Define bean definition reader 
    XmlBeanDefinitionReader xmlBeanDefinitionReader =  new  XmlBeanDefinitionReader ( defaultListableBeanFactory ) ; // Read bean definition 
    int from resource through bean definition reader
    i = xmlBeanDefinitionReader . loadBeanDefinitions ( classPathResource ) ; 
    System . out . println ( "The number of bean definitions is: "  + i ) ; 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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 >
     <!-- If you import yourself here, an org.springframework.beans.factory.BeanDefinitionStoreException will occur-->
    <!--<import resource="testbeandefinition.xml"/>-->
 </ beans >
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

The final call to the code:

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());
}
  • 1
  • 2
  • 3
  • 4
  • 5

where the code to get the validation modegetValidationModeForResource(resource),We have analyzed it in this article . The entry method for our analysis isthis.documentLoader.loadDocument. Let's analyze firstthis.documentLoader.

3:DocumentLoader

DocumentLoader full class nameorg.springframework.beans.factory.xml.DocumentLoader, is a top-level interface. Defines the function of converting from a resource file to a Document document object, and only one method is as follows:

org.springframework.beans.factory.xml.DocumentLoader
public interface DocumentLoader {
	Document loadDocument(
			InputSource inputSource, EntityResolver entityResolver,
			ErrorHandler errorHandler, int validationMode, boolean namespaceAware)
			throws Exception;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Take a look at the parameters:

inputSource: the resource to be parsed
entityResolver: resolver for parsing files
errorHandler: handles errors that occur during parsing of the file
validationMode: xml file validation mode DTD (Document Type Definition) OR XSD (Xml Schema Definition)
namesapceAware: xml namespace support, true is supported, false is not supported
  • 1
  • 2
  • 3
  • 4
  • 5

Let's debug and see these parameters:
insert image description here
the interface has only one implementation classorg.springframework.beans.factory.xml.DefaultDocumentLoader, which implements the loading methodloadDocumentWe will explain in one part.

3.1:loadDocument

The source code is as follows:

org.springframework.beans.factory.xml.DefaultDocumentLoader#loadDocument
@Override
public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
		ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {
	// <2021-02-26 17:25> 创建文档构造器工厂
	DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode,namespaceAware ) ; 
	if  ( logger . isTraceEnabled ( ) )  { 
		logger . trace ( "Using JAXP provider ["  + factory . getClass ( ) . getName ( )  +  "]" ) ; 
	} 
	// <2021-02-26 17:26 Create a document builder via the document builder factory 
	DocumentBuilder builder =  createDocumentBuilder ( factory , entityResolver , errorHandler ) ; 
	return builder.parse(inputSource);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

<2021-02-26 17:25>The code here creates a document constructor factory, and its source code is as follows:

org . springframework . beans . factory . _ _ _
 _ _ _ _ _ _ _  _ _ _ 
			_ _ _ 
	_ 
	_ Instance object 
	DocumentBuilderFactory factory = DocumentBuilderFactory . newInstance ( ) ; 
	// Set up namespace support 
	factory .setNamespaceAware ( namespaceAware ) ; 
	// If there is a validation mode, it is currently xsd VALIDATION_XSD 
	if  ( validationMode != XmlValidationModeDetector . VALIDATION_NONE )  { 
		// Enable the validation 
		factory . setValidating ( true ) ; 
		// If it is xsd, it is mandatory to enable namespace support 
		if  ( validationMode == XmlValidationModeDetector . VALIDATION_XSD )  { 
			// Enforce namespace aware for XSD... 
			factory . setNamespaceAware ( true ) ;
			try {
				// 设置SCHEMA_LANGUAGE_ATTRIBUTE属性
				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.");
				// <2021-02-26 18:38>
				pcex.initCause(ex);
				throw pcex;
			}
		}
	}

	return factory;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

<2021-02-26 18:38>The code is set to cause an exception. For the method initCause, please refer to here .
<2021-02-26 17:26>The code here creates a document constructor through the document constructor factory
, and its source code is as follows:

org.springframework.beans.factory.xml.DefaultDocumentLoader#createDocumentBuilder
protected DocumentBuilder createDocumentBuilder(DocumentBuilderFactory factory,
			@Nullable EntityResolver entityResolver, @Nullable ErrorHandler errorHandler)
			throws ParserConfigurationException {
	// 通过工厂创建文件构造器
	DocumentBuilder docBuilder = factory.newDocumentBuilder();
	// <2021-02-26 18:50>
	// If the resolver to parse the file is not null, set 
	if  ( entityResolver != null )  { 
		docBuilder . setEntityResolver ( entityResolver ) ; 
	} 
	// If the error handler is not null, set 
	if  ( errorHandler != null )  { 
		docBuilder . setErrorHandler ( errorHandler ) ; 
	} 
	// return factory constructor 
	return docBuilder ; 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

<2021-02-26 18:50>The code here is to set the entity parser, the function is to find the constraint file, the DTD type is the corresponding.dtdfile, the XSD type is the corresponding.xsdfile, the corresponding interface isorg.xml.sax.EntityResolveris in jdkrt.jarIt is not a function provided by spring itself. The source code is as follows:

org.xml.sax.EntityResolver#resolveEntity
public interface EntityResolver {

    public abstract InputSource resolveEntity (String publicId,
                                               String systemId)
        throws SAXException, IOException;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

As you can see there is only one wayresolveEntity, There are two parameters, the first is publicId, the second is systemId, the second parameter systemId represents the address of the constraint file, the parameter values ​​in this example are as follows:
insert image description here
ParametersentityResolverThe get is in the method callorg.springframework.beans.factory.xml.DocumentLoader#loadDocumentpassedorg.springframework.beans.factory.xml.XmlBeanDefinitionReader#getEntityResolvermethod, the method is as follows:

org . springframework . beans . factory . _ _ _
 _ _ _ _ _  _ 
	_ 
	_  _ _ _ _ _ _ _  _ 
		_ 32> 
		// Get the resource loader 
		ResourceLoader resourceLoader =  getResourceLoader ( ) ; 
		// If the resource loader is not empty, directly create a new ResourceEntityResolver, and the final return is this object 
		if  ( resourceLoader!= null )  { 
			this . entityResolver =  new  ResourceEntityResolver ( resourceLoader ) ; 
		} 
		// else return DelegatingEntityResolver object 
		else  { 
			this . entityResolver =  new  DelegatingEntityResolver ( getBeanClassLoader ( ) ) ; 
		} 
	} 
	// return final entity resolver 
	return  this . entityResolver ; 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

<2021-02-28 09:32>The code here is to get the resource loader. You can refer to the resource loader here . If there is a resource loader, create a resource entity resolver ResourceEntityResolver, which is defined as follows:

public class ResourceEntityResolver extends DelegatingEntityResolver {}
  • 1

inDelegatingEntityResolverDefined as follows:

public class DelegatingEntityResolver implements EntityResolver {}
  • 1

Next we look atEntityResolverA concrete subclass of implements the logic for finding constraints files.

4:EntityResolver

4.1:DelegatingEntityResolver

This is a direct subclass of Spring's implementation of EntityResolver. This class is a proxy class. According to the specific verification mode, the specific subclass is called for verification. The proxy source code is as follows:

org.springframework.beans.factory.xml.DelegatingEntityResolver
public class DelegatingEntityResolver implements EntityResolver {

	/** Suffix for DTD files. */
	public static final String DTD_SUFFIX = ".dtd";

	/** Suffix for schema definition files. */ 
	public  static  final String XSD_SUFFIX =  ".xsd" ; 
	// entity resolver for dtd validation schema 
	private  final EntityResolver dtdResolver ; 
	// entity resolver for xsd validation schema 
	private  final EntityResolver schemaResolver ;

	@Override 
	@Nullable 
	public InputSource resolveEntity ( @Nullable String publicId ,  @Nullable String systemId ) 
			throws SAXException , IOException { 
		// Only process with systemId, systemId marks the verification file information 
		if  ( systemId != null )  { 
			// If it is dtd then use this.dtdResolver 
			if  ( systemId . endsWith ( DTD_SUFFIX ) )  { 
				return  this . dtdResolver . resolveEntity (publicId , systemId ) ; 
			} 
			// if xsd use this.schemaResolver 
			else  if  ( systemId . endsWith ( XSD_SUFFIX ) )  { 
				return  this . schemaResolver . resolveEntity ( publicId , systemId ) ; 
			} 
		}

		// None of them match, return null, then use the default network download method to obtain 
		return null ; 
	} 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

4.2:BeansDtdResolver

The source code of this class is as follows:

org . springframework . beans . factory . xml . BeansDtdResolver
 public  class  BeansDtdResolver  implements  EntityResolver  { 
	// constraint file extension constant 
	private  static  final String DTD_EXTENSION =  ".dtd" ; 
	// constraint file name constant 
	private  static  final String DTD_NAME =  "spring -beans" ;

	private static final Log logger = LogFactory.getLog(BeansDtdResolver.class);


	@Override
	@Nullable
	public InputSource resolveEntity(@Nullable String publicId, @Nullable String systemId) throws IOException {
		if (logger.isTraceEnabled()) {
			logger.trace("Trying to resolve XML entity with public ID [" + publicId +
					"] and system ID [" + systemId + "]");
		}
		// 地址信息以dtd结尾
		if (systemId != null && systemId . endsWith ( DTD_EXTENSION ) )  { 
			// Get the last/ position 
			int lastPathSeparator = systemId . lastIndexOf ( '/' ) ; 
			// Get the file name address 
			int dtdNameStart = systemId . indexOf ( DTD_NAME , lastPathSeparator ) ; 
			// file name exists 
			if  ( dtdNameStart !=  - 1 )  { 
				// splicing to generate dtd file name
				String dtdFile = DTD_NAME + DTD_EXTENSION;
				if (logger.isTraceEnabled()) {
					logger.trace("Trying to locate [" + dtdFile + "] in Spring jar on classpath");
				}
				try {
					// 构造资源
					Resource resource = new ClassPathResource(dtdFile, getClass());
					// 构造InputSource
					InputSource source = new InputSource(resource.getInputStream());
					// 设置publicId
					source.setPublicId(publicId);
					// 设置systemId
					source.setSystemId(systemId);
					if (logger.isTraceEnabled()) {
						logger.trace("Found beans DTD [" + systemId + "] in classpath: " + dtdFile);
					}
					// 返回
					return source;
				}
				catch (FileNotFoundException ex) {
					if (logger.isDebugEnabled()) {
						logger.debug("Could not resolve beans DTD [" + systemId + "]: not found in classpath", ex);
					}
				}
			}
		}

		// return null, use the default behavior of network download 
		return null ; 
	} 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

4.3:PluggableSchemaResolver

This class has an important propertyDEFAULT_SCHEMA_MAPPINGS_LOCATION,as follows:

public static final String DEFAULT_SCHEMA_MAPPINGS_LOCATION = "META-INF/spring.schemas";
  • 1

The file is defined as follows: It
insert image description here
defines the physical address information of the jar package corresponding to the network address of the xsd, which will eventually be loaded into the variableprivate volatile Map<String, String> schemaMappings;The loading code is as follows:

Properties mappings = PropertiesLoaderUtils.loadAllProperties(this.schemaMappingsLocation, this.classLoader);
schemaMappings = new ConcurrentHashMap<>(mappings.size());
CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings);
this.schemaMappings = schemaMappings;
  • 1
  • 2
  • 3
  • 4

After the loading is completed, the following figure is shown:
insert image description here
Next, let's look at the method of obtaining resources:

org.springframework.beans.factory.xml.PluggableSchemaResolver#resolveEntity
public InputSource resolveEntity(@Nullable String publicId, @Nullable String systemId) throws IOException {
	if (logger.isTraceEnabled()) {
		logger.trace("Trying to resolve XML entity with public id [" + publicId +
				"] and system id [" + systemId +  "]" ) ; 
	} 
	// If systemId is not empty 
	if  ( systemId != null )  { 
		// <2021-02-28 11:26>, get the address in the resource jar package from the mapping map 
		String resourceLocation =  getSchemaMappings ( ) . get ( systemId ) ; 
		// If the address is not obtained, try to use the network address at the beginning of the http protocol to obtain 
		if  ( resourceLocation == null && systemId . startsWith ( "https:" ) )  {
			// Retrieve canonical http schema mapping even for https declaration 
			resourceLocation =  getSchemaMappings ( ) . get ( "http:"  + systemId . substring ( 6 ) ) ; 
		} 
		// If it is not empty, create a ClassPathResource and return 
		if  ( resourceLocation ! = null )  { 
			Resource resource =  new  ClassPathResource ( resourceLocation ,  this . classLoader ) ; 
			try  {
				InputSource source = new InputSource(resource.getInputStream());
				// 设置publicId,systemId
				source.setPublicId(publicId);
				source.setSystemId(systemId);
				if (logger.isTraceEnabled()) {
					logger.trace("Found XML schema [" + systemId + "] in classpath: " + resourceLocation);
				}
				// 返回
				return source;
			}
			catch (FileNotFoundException ex) {
				if (logger.isDebugEnabled()) {
					logger.debug("Could not find XML schema [" + systemId + "]: " + resource, ex);
				}
			}
		}
	}

	// Fall back to the parser's default behavior.
	return null;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

<2021-02-28 11:26>where the code is fromMETA-INF/spring.schemaThe mapping relationship between the URL address of the constraint file and the address in the jar package is loaded in the file. The source code is as follows:

org.springframework.beans.factory.xml.PluggableSchemaResolver#getSchemaMappings
private Map<String, String> getSchemaMappings() {
		Map<String, String> schemaMappings = this.schemaMappings;
	if (schemaMappings == null) {
		synchronized (this) {
			schemaMappings =  this . schemaMappings ; 
			if  ( schemaMappings == null )  { 
				if  ( logger . isTraceEnabled ( ) )  { 
					logger . trace ( "Loading schema mappings from ["  +  this . schemaMappingsLocation +  "]" ) ; 
				} 
				try  { 
					// from Load the verification file URL and jar package address mapping relationship in the spring.schema file 
					Properties mappings = 
							PropertiesLoaderUtils .loadAllProperties(this.schemaMappingsLocation, this.classLoader);
					if (logger.isTraceEnabled()) {
						logger.trace("Loaded schema mappings: " + mappings);
					}
					schemaMappings = new ConcurrentHashMap<>(mappings.size());
					CollectionUtils.mergePropertiesIntoMap ( mappings , schemaMappings ) ; 
					this . schemaMappings = schemaMappings ; 
				} 
				catch  ( IOException ex )  { 
					throw  new  IllegalStateException ( 
							"Unable to load schema mappings from location ["  +  this . schemaMappingsLocation +  "]" , ex ) ; 
				} 
			} 
		} 
	} 
	// return schema mapping dictionary 
	return schemaMappings ; 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

4.4:ResourceEntityResolver

Source code:

org . springframework . beans . factory . xml . ResourceEntityResolver#resolveEntity
 public InputSource resolveEntity ( @Nullable String publicId ,  @Nullable String systemId ) 
			throws SAXException , IOException { 
	// <2021-02-28 12:40>, call the parent class method directly Get 
	InputSource source =  super . resolveEntity ( publicId , systemId ) ; 
	// If it is not obtained, and systemId is not null 
	if  (source == null && systemId != null )  { 
		String resourcePath = null ; 
		try  { 
			// use u8 encoding 
			String decodedSystemId = URLDecoder . decode ( systemId ,  "UTF-8" ) ; 
			String givenUrl =  new  URL ( decodedSystemId ) . toString ( ) ; 
			// <2021-02-28 12:41> 
			// Get the project address of the file:// protocol 
			String systemRootUrl =  new  File("").toURI().toURL().toString();
			// Try relative to resource base if currently in system root.
			if (givenUrl.startsWith(systemRootUrl)) {
				resourcePath = givenUrl.substring(systemRootUrl.length());
			}
		}
		catch (Exception ex) {
			// Typically a MalformedURLException or AccessControlException.
			if (logger.isDebugEnabled()) {
				logger.debug("Could not resolve XML entity [" + systemId + "] against system root URL", ex);
			}
			// No URL (or no resolvable URL) -> try relative to resource base.
			resourcePath = systemId;
		}
		if (resourcePath != null) {
			if (logger.isTraceEnabled()) {
				logger.trace("Trying to locate XML entity [" + systemId + "] as resource [" + resourcePath + "]");
			}
			Resource resource = this.resourceLoader.getResource(resourcePath);
			source = new InputSource(resource.getInputStream());
			source.setPublicId(publicId);
			source.setSystemId(systemId);
			if (logger.isDebugEnabled()) {
				logger.debug("Found XML entity [" + systemId + "]: " + resource);
			}
		}
		else if (systemId.endsWith(DTD_SUFFIX) || systemId.endsWith(XSD_SUFFIX)) {
			// External dtd/xsd lookup via https even for canonical http declaration
			String url = systemId;
			if (url.startsWith("http:")) {
				url = "https:" + url.substring(5);
			}
			try {
				// 创建InputSource并设置publicId,sysetemId信息
				source = new InputSource(new URL(url).openStream());
				source.setPublicId(publicId);
				source.setSystemId(systemId);
			}
			catch (IOException ex) {
				if (logger.isDebugEnabled()) {
					logger.debug("Could not resolve XML entity [" + systemId + "] through URL [" + url + "]", ex);
				}
				// Fall back to the parser's default behavior.
				source = null;
			}
		}
	}

	return source;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

<2021-02-28 12:40>, the method called here isorg.springframework.beans.factory.xml.DelegatingEntityResolver#resolveEntityhas been analyzed previously.<2021-02-28 12:41>The code here is to obtain the project root path address of the file:// protocol, such asfile:/Users/xb/Desktop/D/dongsir-dev/java-life-current/java-life/is my local result value, which is used to find the constraint file from the system root path, in other words, to deal with the case where the constraint file is in the system root path.

5: Get Document

final call methodorg.springframework.beans.factory.xml.DefaultDocumentLoader#loadDocumentTo get the document object, the code is as follows:

org.springframework.beans.factory.xml.DefaultDocumentLoader#loadDocument
@Override
public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
		ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {

	DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
	if (logger.isTraceEnabled()) {
		logger.trace("Using JAXP provider [" + factory.getClass().getName() + "]");
	}
	DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
	return builder.parse(inputSource);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

So far, the document corresponding to the xml file has been successfully passed, and the next step is to analyze how to parse it into a BeanDefinition. For details, refer to here .

Tags: Spring IOC obtains Document object analysis based on xml file

spring java spring 5

Related: Spring IOC obtains Document object analysis based on xml file