07.Spring Bean Load-beandefinitionreader

Source: Internet
Author: User
Tags throw exception

Basic concepts

Beandefinitionreader, the function of this interface is to load the Bean.

In Spring, beans are generally defined in a configuration file. The path that is configured is defined in Web. Xml. So the steps to load the Bean are basically:

    • Load a resource, load a profile (Resource) from a configuration file path (location)

    • Parse the resource to get the Bean by parsing the contents of the configuration file.

Here's an interface definition:

Publicinterface beandefinitionreader {BeanDefinitionRegistry GetRegistry (); Resourceloader Getresourceloader (); ClassLoader Getbeanclassloader (); Beannamegenerator Getbeannamegenerator (); //through Resource load Bean int loadbeandefinitions (Resource Resource) throws beandefinitionstoreexception; int loadbeandefinitions (Resource ... resources) throws Beandefinitionstoreexception; //load resources through location int loadbeandefinitions (String location) Span class= "Hljs-keyword" >throws beandefinitionstoreexception; int loadbeandefinitions (String ... locations) throws beandefinitionstoreexception;}            

The specific inheritance relationship is as follows:

Process Analysis

First, the Spring Ioc container starts from start to call Beandefinitionreader to load the Bean as follows:

Note: Because the XML file is used here as a Spring configuration file, Xmlbeandefinitionreader is called by default to handle it.

1. Loading beans via Beanfactory

Within the Spring container (ApplicationContext) There is an internal container (beanfactory) responsible for the creation and management of the Bean.

After creating the Beanfactory, the next step is to load the Bean. It is the responsibility of the Loadbeandefinitions method.

ProtectedvoidLoadbeandefinitions (Defaultlistablebeanfactory beanfactory)Throws Beansexception, IOException {1. Create Beandefinitionreader Xmlbeandefinitionreader Beandefinitionreader =New Xmlbeandefinitionreader (beanfactory);2. Setting the Beandefinitionreader Properties2.1. Set the environment, i.e. the environment, in accordance with the environment of the container Beandefinitionreader.setenvironment (Getenvironment ());//2.2. Set Resourceloader, which is the resource loader, because the container implements the interface, the function of loading the resources beandefinitionreader.setresourceloader (this); //2.3. Set Entityresolver, the entity resolver, which is used to parse the resource content loaded by the resource loader beandefinitionreader.setentityresolver (new Resourceentityresolver (this)); //3. Initialize Beandefinitionreader, empty method Initbeandefinitionreader (Beandefinitionreader); //4. Load Bean loadbeandefinitions (beandefinitionreader) via Beandefinitionreader;} //Constructor public  Xmlbeandefinitionreader (Beandefinitionregistry registry) { //internal beanfactory is treated as Bean registrar super (registry);}           

Observing the code, the main purpose of the method is to create a beandefinitionreader and to load the Bean. The process is as follows:

    • Create Beandefinitionreader
    • Setting the related properties of Beandefinitionreader
    • Initialize Beandefinitionreader
    • Loading beans through Beandefinitionreader
2. Loading beans via Beandefinitionreader

After the Beandefinitionreader is created, it is necessary to load the Bean with the following procedure:

// 通过 BeanDefinitionReader 加载 Bean protected void loadBeanDefinitions(XmlBeanDefinitionReader reader)     throws IOException { // 取得 Spring 容器的所有配置文件 String[] configLocations = getConfigLocations(); if (configLocations != null) { for (String configLocation : configLocations) { // 调用 BeanDefinitionReader 加载 Bean reader.loadBeanDefinitions(configLocation); } }}
3. Loading beans via location

The responsibility for the loaded Bean is given to Beandefinitionreader, and the following is a look at the Loadbeandefinitions method of the class.

PublicIntLoadbeandefinitions (String location)Throws Beandefinitionstoreexception {return Loadbeandefinitions (location,NULL);}PublicIntLoadbeandefinitions (String location, set<resource> actualresources)Throws Beandefinitionstoreexception {1. Obtain the resource loader, which is the container itself resourceloader Resourceloader = Getresourceloader ();if (Resourceloader = =NULL) {Throw exception ...}Determine the resource loader typeif (ResourceloaderInstanceof Resourcepatternresolver) {Indicates that the Resourceloader can load multiple resources based on a pathtry {2. Load resource resource[] resources = ((Resourcepatternresolver) resourceloader). getresources (location);3. Loading beans via Resourceint Loadcount = loadbeandefinitions (resources); if (actualresources! = null) {for (Resource resource:resources) {Actualresources.add (Resource);} } //omit code ... return Loadcount;} catch (IOException ex) {//throws an exception ...}} else {//means Resourceloader can only load one resource Resource Resource = Resourceloader.getresource (location); int loadcount = loadbeandefinitions (Resource); if (actualresources! = null) {Actualresources.add (Resource);} //omit code ... return loadcount;}           

Observation code, the workflow of this method can be divided into four steps:

    • Get the resource loader

    • Load resources, load with Resourceloader via location

    • Loading beans through Resource

4. Loading beans via Resource

After the resource (Resource) is obtained, the method encapsulates it and makes it a Encodedresource object.

public int loadBeanDefinitions(Resource resource)     throws BeanDefinitionStoreException {    // EncodedResource 表示编码类型的资源 return loadBeanDefinitions(new EncodedResource(resource));}// 构造函数public EncodedResource(Resource resource, String encoding) { // 封装资源,并带上编码类型 this(resource, encoding, null);}
5. Loading beans via Encodedresource
PublicIntLoadbeandefinitions (Encodedresource Encodedresource)Throws Beandefinitionstoreexception {Omit code ...1. Obtain a collection of [loaded resources] for the presence of loaded resources. Empty, it is created. Set<encodedresource> currentresources =This.resourcesCurrentlyBeingLoaded.get ();if (currentresources = =NULL) {currentresources =New Hashset<encodedresource> (4);This.resourcesCurrentlyBeingLoaded.set (currentresources); }2. Add the current resource to the collectionif (!currentresources.add (Encodedresource)) {Throw exception ...}try {3. Convert the resource to stream inputstream InputStream = Encodedresource.getresource (). getInputStream ();try {//5. Create InputSource via stream and set encoding inputsource InputSource = new InputSource (InputStream); if (encodedresource.getencoding ()! = null) { Inputsource.setencoding (Encodedresource.getencoding ()); } //6. InputSource load Bean return doloadbeandefinitions ( InputSource, Encodedresource.getresource ()); }finally {inputstream.close ();}} catch (IOException ex) {//throws an exception ...} finally {//remove the resources that have been resolved currentresources.remove ( Encodedresource); //collection is empty, then delete if (Currentresources.isempty ()) {this.resourcescurrentlybeingloaded.remove (); } }} 
    • Get the loaded resource collection
    • To add the current resource to the collection
    • Convert a resource into a stream
    • Create a inputsource with a stream and set the encoding
    • Loading beans through InputSource
6. Loading beans via InputSource

The reason for converting Resource to InputSource is to prepare for SAX parsing.

ProtectedIntDoloadbeandefinitions (InputSource InputSource, Resource Resource)Throws Beandefinitionstoreexception {try {1. Parse XML file doc = doloaddocument (InputSource, Resource);2. Registering beansReturn Registerbeandefinitions (Doc, Resource); }catch (Beandefinitionstoreexception ex) {Throw exception ...}catch (Saxparseexception ex) {//throws an exception ...} catch (Saxexception ex) {//throws an exception ...} catch (Parserconfigurationexception ex) {//throws an exception ...} catch (IOException ex) {//throws an exception ...} catch (Throwable ex) {//throws an exception ...}} //parse the XML file and return the Document object. protected Document doloaddocument (InputSource InputSource, Resource Resource) throws Exception {return this.documentloader.loaddocument (InputSource, Getentityresolver (),  This.errorhandler, Getvalidationmodeforresource (Resource), Isnamespaceaware ());}       
3.Bean Registration

In the previous step, Xmlbeandefinitionreader has obtained the Document object of XML, and completed the parsing process of the resource.

The next step is the Bean registration process.

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {    // 利用 documentReader 对配置文件的内容进行解析 BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); // 取得已经注册 BeanDefinition int countBefore = getRegistry().getBeanDefinitionCount(); // 关键 -> 注册 BeanDefinition (包含解析过程) documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); return getRegistry().getBeanDefinitionCount() - countBefore;}
Summarize

After analyzing the specific work flow of beandefinitionreader, finally, a simple diagram is presented:

07.Spring Bean Load-beandefinitionreader

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.