Spring Source Inquiry-Beandefinitionreader

Source: Internet
Author: User

Basic Concepts

Beandefinitionreader , the function of this class is to read the contents of the Spring configuration file and convert it into a data structure inside the IOC container, and the container's data structure is beandefinition.

The functionality of this class can be summed up in two steps:

    • Responsible for the resource orientation of beandefinition

    • In charge of beandefinition loading

Here's an interface definition:

 Public  interface beandefinitionreader {Beandefinitionregistry GetRegistry ();    Resourceloader Getresourceloader ();    ClassLoader Getbeanclassloader (); Beannamegenerator Getbeannamegenerator ();//Key---responsible for beandefinition loading, reading resrouce content, through Beandefinitiondocumentreader to parse it into Beandefinition    intLoadbeandefinitions (Resource Resource)throwsBeandefinitionstoreexception;intLoadbeandefinitions (Resource ... resources)throwsBeandefinitionstoreexception;//Key---responsible for beandefinition resource positioning, using Resourceloder to obtain resrouce instance according to path    intLoadbeandefinitions (String location)throwsBeandefinitionstoreexception;intLoadbeandefinitions (String ... locations)throwsBeandefinitionstoreexception;}

Then look at its inheritance:

Source Analysis

First, the Spring Ioc container starts from start to call the Beandefinitionreader process.

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

Here's a look at Xmlbeandefinitionreader's workflow:

 Public int loadbeandefinitions(String location)throwsbeandefinitionstoreexception {returnLoadbeandefinitions (Location,NULL);} Public int loadbeandefinitions(String location, set<resource> actualresources)throwsbeandefinitionstoreexception {//Step one: Get the resource loaderResourceloader Resourceloader = Getresourceloader ();//Step two: Check the resource loader (to determine if it is empty)    if(Resourceloader = =NULL) {//Throw an exception ...}//Step two: Verify the resource loader (determine if the Resourcepatternresolver interface is implemented)    if(ResourceloaderinstanceofResourcepatternresolver) {//Resource pattern matching available.        Try{//Step three: Resource orientation of key---Beandefinitionresource[] Resources = ((Resourcepatternresolver) resourceloader). getresources (location);//Step four: Loading of key---Beandefinition            intLoadcount = loadbeandefinitions (resources);if(Actualresources! =NULL) { for(Resource resource:resources)                {Actualresources.add (Resource); }            }//Log Output ...            returnLoadcount; }Catch(IOException ex) {//Throw an exception ...}    }Else{Resource Resource = resourceloader.getresource (location);intLoadcount = loadbeandefinitions (Resource);if(Actualresources! =NULL) {Actualresources.add (Resource); }//Log Output ...        returnLoadcount; }}

Observing the code, the Beandefinitionreader workflow can be divided into four steps:

    • Get Resourceloader

    • Check Resourceloader

    • Resource orientation of beandefinition

    • Loading of Beandefinition

Once again, the Beandefinitionreader function is verified by code, and then the next two steps are explored in detail.

1.BeanDefinition Resource Positioning

Resource positioning is the process of getting an Resource instance object. The beandefinitionreader itself does not have this function, but instead obtains the Resource instance through resourceloader .

The above mentioned Beandefinitionreader will be to determine whether Resourceloader implement Resourcepatternresolver interface, the essence is to determine whether the Resourceloader support Access multiple resources at the same time .

    • If multiple resources are supported concurrently, the Resrouce array is returned.
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);

First, let's look at the inheritance relationship of the Resourcepatternresolver interface:

Here Xmlbeandefinitionreader will default to calling the Getresources method of the parent class Abstractapplicationcontext:

publicgetResourcesthrows IOException {    // 此时 resourcePatternResolver 为 ServletContextResourcePatternResolver    returnthis.resourcePatternResolver.getResources(locationPattern);}

The servletcontextresourcepatternresolver will then call the parent class Pathmatchingresourcepatternresolver by default. Getresources method.

Pathmatchingresourcepatternresolver in the introduction of Resourceloader has been explored here is not detailed.

The entire invocation process is as follows:

    • If simultaneous access to multiple resources is not supported, a single Resource object is returned:
Resource resource = resourceLoader.getResource(location);

The whole resource positioning process is relatively simple, which is closely related to the two classes of Resource and Resourceloader. Spring does this by abstracting the different types of resources into the Resrouce interface, and then by Resourceloader, so that spring is only coupled to the Resource interface and no longer cares about what type of resource access is used at the bottom.

2.BeanDefinition Loading

Loading, refers to the process of reading Resource content and loading it as a doucument.

Here's a look at the specific process:

    • Get Resource, add encoded information, and turn it into encodedresource
publicintloadBeanDefinitionsthrows BeanDefinitionStoreException {    // 将 resource 包裹在 EncodedResource 中,其实例化过程会为 Resource 添加编码信息,这里默认编码信息为 null    return loadBeanDefinitions(new EncodedResource(resource));}
    • Ready to start reading the content by getting the input stream of the Resource and adding it into the InputSource
 Public int loadbeandefinitions(Encodedresource Encodedresource)throwsbeandefinitionstoreexception {assert.notnull (Encodedresource,"Encodedresource must not being null");//Log Output ...    //Get resources that have been loadedSet<encodedresource> currentresources = This. Resourcescurrentlybeingloaded.get ();//If no loaded resources exist, create a new HashSet to load after storage    if(Currentresources = =NULL) {currentresources =NewHashset<encodedresource> (4); This. Resourcescurrentlybeingloaded.set (Currentresources); }//Add the current resource into the HashSet    if(!currentresources.add (Encodedresource)) {//If the current resource already exists, throw an exception ...}Try{//All types of Resource can be converted into stream operationsInputStream InputStream = Encodedresource.getresource (). getInputStream ();Try{//Add stream to InputSource to prepare for SAX parsingInputSource InputSource =NewInputSource (InputStream);//Set encoding            if(encodedresource.getencoding ()! =NULL) {inputsource.setencoding (encodedresource.getencoding ()); }//Key--Start the real beandefinitions loading process            returnDoloadbeandefinitions (InputSource, Encodedresource.getresource ()); }finally{Inputstream.close (); }    }Catch(IOException ex) {//Throw an exception ...}finally{//Last exception to the currently loaded resourceCurrentresources.remove (Encodedresource);//resource Set if empty, remove together        if(Currentresources.isempty ()) { This. Resourcescurrentlybeingloaded.remove (); }    }}
    • Because Spring uses an XML configuration file here, the document object is obtained using SAX parsing
protected int doloadbeandefinitions(InputSource InputSource, Resource Resource)throwsbeandefinitionstoreexception {Try{//Using SAX parsing to get the document object of an XML fileDocument doc = doloaddocument (InputSource, Resource);//Key---parse and register beandefinitions        returnRegisterbeandefinitions (Doc, Resource); }Catch(Beandefinitionstoreexception ex) {//Throw an exception ...}Catch(Saxparseexception ex) {//Throw an exception ...}Catch(Saxexception ex) {//Throw an exception ...}Catch(Parserconfigurationexception ex) {//Throw an exception ...}Catch(IOException ex) {//Throw an exception ...}Catch(Throwable ex) {//Throw an exception ...}}

This concludes with a simple overview of the entire onboarding process:

    • Get the Resource and add the encoded information and turn it into Encodedresource.

    • Get Resource input stream, add into InputSource, and SAX parse to prepare.

    • Obtain InputSource, use SAX parse to get Document object, complete loading.

3.BeanDefinition Parsing and registration

In the previous step, Xmlbeandefinitionreader has made the XML Document object and completed the onboarding process. The next thing to do is to beandefinition the parsing and registration process. This feature is specifically implemented by Beandefinitiondocumentreader .

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

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

Spring Source Inquiry-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.