Simple Analysis of Spring IoC container Initialization

Source: Internet
Author: User

First, I would like to share an article on understanding IOC ideas.

Theme: My Understanding of IOC/DI: http://www.iteye.com/topic/1122310

In my opinion, the most important section is as follows:

Key to understanding IOC containers: what aspects of control are reversed?

1. Who controls who? Why is reverse? ------ IOC container control, which was previously application control, is called reverse

2. What is the control? ------ Control the resources required by the application (objects, files ......)

3. Why control? ------ Relationship between decoupled Components

4. What aspects of control are reversed? ------ Control of the program is reversed: From the application to the IOC container

The following is a simple analysis of spring technology insider and spring source code that I have been reading since late November. It takes a long time and is rough.

1. Spring IoC container core data structure

I think beandefinition, resource, beanfactory, and applicationcontext are the core structure of the IOC container.

1.1 beandefinition

Role: Hold the bean data structure, which is the abstraction of the injected bean in the IOC container

The method list is as follows:

getBeanClassName;getFactoryBeanName;getScope;isLazyInit;isSingleton;isPrototype;isAbstract;isPrimary;isAutowireCandidate;getDescription;

Beandefinition-related classes:

Abstractbeandefinition, beandefinitionreader

Abstractbeandefinition is a complete implementation of beandefinition.

Beandefinitionreader is used to read bean information. abstractbeandefinitionreader implements this interface. xmlbeandefinitionreader inherits abstractbeandefinitionreader.

1.2 Resource

For the abstract of the resource file, the inputstream getinputstream () throwsioexception method is finally implemented.

The method list is as follows:

exists();isReadable();getURL();getURI();getFile();contentLength();lastModified();getFilename();getDescription();

1.3 beanfactory

It is extremely important to obtain the Bean factory, the most basic IOC container

getBean();containsBean();isSingleton();isPrototype();isTypeMatch();getType();getAliases();

1.4 applicationcontext

In addition to basic IOC container functions, advanced IOC containers support different information sources, resource access, event publishing, and other functions.

Inherited the following interface

Listablebeanfactory, hierarchicalbeanfactory, messagesource, applicationeventpublisher, resourcepatternresolver

 

Five Interfaces

The listablebeanfactory interface inherits beanfactory. On this basis, methods such as containsbeandefinition, getbeandefinitioncount, and getbeandefinitionnames are added.

The hierarchicalbeanfactory interface inherits beanfactory. Based on this, the getparentbeanfactory and containslocalbean methods are added.

Messagesource is used to obtain international information. For the so-called international information, if we are developing a web application that supports multiple languages, the system is required to return the corresponding interface according to the language type of the Client System: The English operating system returns the English interface, the Chinese operating system returns the Chinese interface, which is a typical i18n internationalization problem. For application systems with international requirements, we cannot simply write user interface information, error messages, and other content in a hard-coded manner, but must perform special processing for these international information. Simply put, a set of corresponding resource files is provided for each language and saved in a specific directory in a standardized naming manner. The system automatically selects the appropriate resource files based on the client language.

Applicationeventpublisher is the spring event publisher interface. Because applicationcontext implements this interface, spring's applicationcontext instance has the function of releasing events.

Resourcepatternresolver: Resource loader for device resource usage.

Applicationcontext provides external methods such as GETID () and getdisplayname.


2 IOC container Initialization

The initialization of the IOC container is the four processes of locating, loading, parsing, and registering the resource containing beandefinition information. Finally, the bean we configured exists in the IOC container as the memory using the beandefinition data structure. This does not involve bean dependency injection and does not produce any beans.

2.1beandefinition

In the abstractbeandefinitionreader. loadbeandefinitions () method, the getresource () method of defaultresourceloader is called. Here is the location of resouce, as shown below:

public Resource getResource(String location) {Assert.notNull(location, "Location must not be null");if (location.startsWith(CLASSPATH_URL_PREFIX)) {return newClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());}else {try {// Try to parse the location as a URL...URL url = new URL(location);return new UrlResource(url);}catch (MalformedURLException ex) {// No URL -> resolve as resource path.return getResourceByPath(location);}}}

The implementation of getresourcebypath is as follows:

protected Resource getResourceByPath(String path) {return new ClassPathContextResource(path, getClassLoader());}

2.2 beandefinition Loading

Beandefinition is loaded into xmlbeandefinitionreader using the loadbeandefinitions () method:

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {Assert.notNull(encodedResource, "EncodedResource must not be null");if (logger.isInfoEnabled()) {logger.info("Loading XML bean definitions from " + encodedResource.getResource());}Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();if (currentResources == null) {currentResources = new HashSet<EncodedResource>(4);this.resourcesCurrentlyBeingLoaded.set(currentResources);}if (!currentResources.add(encodedResource)) {throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");}try {InputStream inputStream = encodedResource.getResource().getInputStream();try {InputSource inputSource = new InputSource(inputStream);if (encodedResource.getEncoding() != null) {inputSource.setEncoding(encodedResource.getEncoding());}return doLoadBeanDefinitions(inputSource, encodedResource.getResource());}finally {inputStream.close();}}catch (IOException ex) {throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), ex);}finally {currentResources.remove(encodedResource);if (currentResources.isEmpty()) {this.resourcesCurrentlyBeingLoaded.remove();}}}

The doloadbeandefinitions () method implements the following in this class:

Protected int doloadbeandefinitions (inputsource, resource Resource) throws beandefinitionstoreexception {try {int validationmode = getvalidationmodeforresource (Resource); document DOC = this.doc umentloader. loaddocument (inputsource, getentityresolver (), this. errorhandler, validationmode, isnamespaceaware (); Return registerbeandefinitions (Doc, resource);} catch () {// Exception Handling }}

Saxparseexception is thrown. You can see that the spring XML parsing tool is sax.

 

2.3 beandefinition Parsing

Beandefinition is parsed in the parsebeandefinitionelement (elementele, beandefinition containingbean) method of the beandefinition parserdelegate class.

This method is called first

String id = ele.getAttribute(ID_ATTRIBUTE);String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

Obtain the bean ID and bean name.

Next, call

AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean)

Parse bean elements in detail and call

Parsebeandefinitionattributes () parses bean attributes;

Parsepropertyelements (Ele, BD) parses the bean property.

Bean attributes are injection attributes such as scope, islazyinit, autowire, and sigleton. They are all done in a similar way:

if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {// Spring 2.x "scope" attributebeanDefinition.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));}

Call the Set Method of beandefinition.

The method for parsing propterty is described in the parsepropertyelements () method, mainly as follows:

1. If there is a propterty with the same name in the bean definition, only the first property will be parsed, and subsequent propterty with the same name will not be processed.

2. Determine whether it is ref or value.

2.4 Register beandefinition

Beandefinition registration means to let IOC know how beandefinition exists and how to get beandefinition. In defaultlistenerablebeanfactory, you can use a hashmap <string, beandefinition> to operate on each beandefinition.

In defaultlistenablebeanfactoryPublicvoidRegisterbeandefinition (string beanname, beandefinition)ThrowsBeandefinitionstoreexception

This step is completed.

Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);if (oldBeanDefinition != null) {if (!this.allowBeanDefinitionOverriding) {throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +"': There is already [" + oldBeanDefinition + "] bound.");}else {if (this.logger.isInfoEnabled()) {this.logger.info("Overriding bean definition for bean '" + beanName +"': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");}}}else {this.beanDefinitionNames.add(beanName);this.frozenBeanDefinitionNames = null;}this.beanDefinitionMap.put(beanName, beanDefinition);

Finally, beandefinitionmap is used to operate beandefinition.

2.5 IOC container startup

The filesystemxmlapplicationcontext constructor starts the IOC container as follows.

Public filesystemxmlapplicationcontext (string [] configlocations, Boolean refresh, applicationcontext parent) throws beansexception {super (parent); setconfiglocations (configlocations); If (refresh) {refresh ();}}

The refresh () method is implemented in the abstractapplicationcontext parent class of filesystemxmlapplicationcontext. In the refresh () method, the refreshbeanfactory () method is finally called.

 

Complete IOC container startup analysis (taking filesystemxmlapplicationcontext as an example)

1. The filesystemxmlapplicationcontext constructor calls the refresh () method. Here is the entry to load beandefinition.

2. the refresh () method is located in the parent class of filesystemxmlapplicationcontext.

In abstractapplicationcontext, call the refreshbeanfactory () method;

3. Subclass of the refreshbeanfactory () method in abstractapplicationcontext

Implementation in abstractrefreshableapplicationcontext,

Call the loadbeandefinition () method to start loading beandefinition;

4. loadbeandefinition () is implemented in abstractxmlapplicationcontext, And the loadbeandefinitions () method of xmlbeandefinitionreader is called.

5. loadbeandefinitionreader's loadbeandefinitions () enables the read of XML files carrying beandefnition definitions, in the I/O mode.

6. After reading, parse beandefinition. Bean parsing adopts the sax tool. It is first parsed according to the XML file format, and then parsed according to the definition of spring bean, which is implemented in beandefinitionparserdelegate. parsebeandefinitionelement.

7. Finally, register the beandefinition information. Put each beandefinition in a hashmap with key = beanname, value = beandefinition, and implement it in defaultlistenablefactoty. registerbeandefinition.

 

After IOC container initialization, the IOC container holds beandefintion, which lays the foundation for calling the getbean () method by injecting bean dependencies.

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.