Spring beanfactory, applicationcontext hierarchy, and beandefinition parsing process

Source: Internet
Author: User

Level Architecture

// Summary of the bucket and Context Levels (and how to fetch water)

// When you are using a class such as filesystemxmlapplicationcontext, you will feel that the method calling in it is complicated and has many layers.
// Let's start with the role and hierarchy of the main classes, so that we can have a general concept and an impression to facilitate subsequent analysis.

Class waterpot {// Bucket: // The Order is basically in the inheritance order. // ***************************** interface Definition branch ************************* // ====== ============ the two most basic interfaces ================================= ====/// interface: the most basic is to include bean acquisition, bean type judgment, and alias array acquisition. // * Org. springframework. beans. factory. beanfactory // interface: Same as hierarchical, it is used hierarchically to obtain the parent beanfactory, and to determine whether beanfactory has a specified bean // * Org. springframework. beans. factory. hierarchicalbeanfactory // ============= Co Nfigurablebeanfactory: Main related resource management of Bean Factory ============/// interface: One of the direct parent interfaces of hierarchicalbeanfactory (also including applicationcontext, it is also a direct parent interface of hierarchicalbeanfactory) // many methods are defined, including (it should mainly be the scenario Resource and Environment specified for Bean factory operations ): // set parentbeanfactory, classloader, tempclassloader, set // whether to cache bean metadata such as given bean definitions (in // merged fashion) for beanfactory) and resolved bean // classes., typeconve Rter assignment, beanpostprocessor addition, etc // * Org. springframework. beans. factory. config. configurablebeanfactory // === configurablelistablebeanfactory: contains the inheritance of retriable, list, And autowire (mainly the in-depth integration of environment definitions) ====/interface: previously, Bean Factory performed a single operation on bean. This operation mainly involves returning and operating multiple returned results // * Org. springframework. beans. factory. listablebeanfactory // interface: related operations of automatic IOC annotation // * Org. springframework. beans. factory. config. autowirecapablebeanfactory // interface: mainly to summarize the previous main interfaces And provides the preinstantiatesingletons method. // Additional definition of automatic assembly: Ignore type, ignore interface, specified binding, etc. // * Org. springframework. beans. factory. config. configurablelistablebeanfactory // ************************** additional special interfaces and implementation branches **** ********************** // ============= ===== various bean registration ======================================================== // interface: alias operation definition // * Org. springframework. core. aliasregistry // implementation: Managing aliases (mainly maintaining the map of aliases) // * Org. springframework. core. simplealiasregistry // interface: Manages and defines beans in the singleton mode, including registration, acquisition, and judgment/ /* Org. springframework. beans. factory. config. singletonbeanregistry // implementation: inherits the alias management implementation and implements single-instance registration (mainly implements the single-instance registration interface and manages Map sets of various types of data) // * Org. springframework. beans. factory. support. defaultsingletonbeanregistry // interface: mainly defines the registration of beandefinition (beandefinition is the raw data of bean Step 2-step Dom parsing data) // * Org. springframework. beans. factory. support. beandefinitionregistry // **************************** integration implementation of various interfaces ***** ********************* * // =================================================================== ============================================/// Implementation: the defaultsingletonbeanregistry is encapsulated for obtaining and maintaining a single instance. // * Org. springframework. beans. factory. support. factorybeanregistrysupport // implementation: Implements configurablebeanfactory, that is, the implementation of resource management. In addition, it inherits factorybeanregistrysupport and further encapsulates bean acquisition. // It is not limited to acquiring a Singleton, but also including obtaining and judging non-singleton instances from the parent factory. // * Org. springframework. beans. factory. support. abstractbeanfactory // implementation: implements the autowirecapablebeanfactory interface and inherits abstractbeanfactory // * Org. springframework. beans. factory. support. abstractautowirecapablebeanfactory // implementation: our main basic container implementation. (There will be various applicationcontext), but the buckets of the original data beandefinition and the buckets of the single instance are mainly defaultlistablebeanfactory // * org. springframework. Beans. Factory. Support. defaultlistablebeanfactory}

Class context {// context //============================ bottom-layer context: applicationcontext ==============================================================/// interface: obtain environment // * Org. springframework. core. env. environmentcapable // interface: the message and policy interface that are resolved with the support of parameterized and internationalized messages. // * Org. springframework. context. messagesource // interface: receives applicationevent // * Org. springframework. context. applicationeventpublisher // interface: Get resources // * Org. springframework. core. io. support. resourcepatternresolver // interface: the most basic context interface. Besides inheriting the preceding interface, it also inherits the two listablebeanfactory and // hierarchicalbeanfactory interfaces of the container. // * Org. springframework. context. applicationcontext // ============================== configurableapplicationcontext ==== ==================================================================/// Interface: the typical use case for this is to control asynchronous processing. // many execution control interfaces are inherited from this interface // * Org. springframework. context. lifecycle // interface: inherits the basic functions of the context from applicationcontext, and defines a large number of environment configuration interfaces (including setenvironment, addbeanfactorypostprocessor, addapplicationlistener, and registershutdownhook ). There is also a major entry refresh () // * Org. springframework. context. configurableapplicationcontext // ================================ basic method implementation of the publish text: abstractapplicationcontext =============================================== // interface: destruction action: destroys the singleton class // * Org. springframework. beans. factory. disposablebean // interface: The policy interface for loading resources // * Org. springframework. core. io. resourceloader // implementation: Default resource loading // * Org. springframework. core. io. defaultresourceloader // implementation: Basic Method Implementation of the launch text (including loading and refreshing portals, initialization container start time, and refresh and rebuilding beanfactory portals (the specific refreshbeanfactory is left by the subclass) prepare bean // Factory (mainly declaring classloader, adding beanpostprocessor //, automatically assembling ignore interface, specifying automatic assembly type matching, registering various Singleton, etc), call beanfactory's postprocessor, these post-processors are registered to the container in the bean definition, initialize the message source in the context, initialize the event mechanism in the context, check the listening bean, and register and instantiate these beans to the container. all (non-Lazy-init) singleton, publish container events, and end the refresh process) // * Org. springframework. context. support. abstractapplicationcontext // ============================ refresh and recreate beanfactory: abstractrefreshableapplicationcontext ============================/// implementation: refreshbeanfactory is an important implementation method to refresh and recreate beanfactory // * Org. springframework. context. support. abstractrefreshableapplicationcontext // ========================== abstractrefreshableconfigapplicationcontext ====== ==========================================/// interface: bean Factory name // * Org. springframework. beans. factory. beannameaware // * Org. springframework. beans. factory. initializingbean // implementation: config setting // * Org. springframework. context. support. abstractrefreshableconfigapplicationcontext // ============================ abstractxmlapplicationcontext ====== ==========================================/// implementation: this is mainly the implementation of loadbeandefinitions. The xmlbeandefinitionreader method is specified internally to read // * Org. springframework. context. support. abstractxmlapplicationcontext // classpathxmlapplicationcontext, filesystemxmlapplicationcontext // the startup entry and "personalized" resource loading}

// ================================================ ============================================================== ==================================

// Resolution Step 1: Read Resources

Class reader {// ============================================ read resources: xmlbeandefinitionreader ======================================================/// analyze xmlbeandefinitionreader organization level // interface: the basic interface for reading and parsing is mainly the four loadbeandefinitions definitions, which are responsible for reading the definition, but do not include the registered definition after reading. // * Org. springframework. beans. factory. support. beandefinitionreader // implementation: beandefinitionreader (string type resource loading, multi-parameter resource traversal, acquisition and assignment of various resources) and environmentcapable interfaces are implemented in simple encapsulation. // (How to read and complete it in the definition of the interface containing the resource parameter in the subclass) // * Org. springframework. beans. factory. support. abstractbeandefinitionreader // implementation: reads files in XML format, and finally provides classes. Read rules and registration rules are specified. (The specific reading and registration should go down) // * org. springframework. Beans. Factory. xml. xmlbeandefinitionreader}

// Parse Step 2: read document
// Defadocumentdocumentloader. Dom Parsing is not mentioned. It is not much different from Dom parsing. We can use many good third-party frameworks at ordinary times.

// Resolution Step 2: beandefinitiondocumentreader (resource integration, or feature extraction)

Class mybeandefinitiondocumentreader {// ======================================== use the document returned by reader to get the matching beandefinition: beandefinitiondocumentreader ==================================/// interface: SPI for parsing an XML document that contains spring bean definitions. // used by xmlbeandefinitionreader for actually parsing a DOM document. // * Org. springframework. beans. factory. XML. beandefinitiondocumentreader // implementation: for reader to call . Combined with the document and xmlreadercontext read by documentloader. // * Org. springframework. Beans. Factory. xml. defaultbeandefinitiondocumentreader}

// Resolution Step 3: parse the document into beandefinition

Class mybeandefinitionparserdelegate {// tool class: Various parsing methods for root rules // * Org. springframework. beans. factory. XML. beandefinitionparserdelegate // use the tool class to help encapsulate and register it into defalistlistablebeanfactory}

Let's talk about the execution process.

============================ Filesystemxmlapplicationcontext ========== ==================================

* Org. springframework. Context. Support. filesystemxmlapplicationcontext

There are many commonly used applicationcontext. We chose filesystemxmlapplicationcontext for portal analysis. (The differences between the implementation of several applicationcontext methods are basically that the resource acquisition and resolution methods are different)

Create:

Public filesystemxmlapplicationcontext (string [] configlocations, Boolean refresh, applicationcontext parent) throws beansexception {super (parent); // sets the resource path, which is completed by the subclass abstractrefreshableconfigapplicationcontext (configlocations ); // load or refresh the persistent representation of the configuration, which might an XML file, properties file, or relational database schema. // loads resources, destroys previous containers, creates containers, resolves resources, instantiate all remaining (non-Lazy-init) singletons, if (refresh) {refresh ();}}

* 1: refresh (): (provided by the basic implementation class abstractapplicationcontext)

Public void refresh () throws beansexception, illegalstateexception {synchronized (this. startupshutdownmonitor) {// prepare this context for refreshing. preparerefresh (); // tell the subclass to refresh the internal Bean factory. // here is the place where refreshbeanfactory () is started in the subclass configurablelistablebeanfactory beanfactory = obtainfreshbeanfactory (); // prepare the Bean Factory for use in this context. preparebeanfactory (beanfactory); try {// allows post-processing of the bean factory in context subclasses. // set postprocessing postprocessbeanfactory (beanfactory) for beanfactory; // invoke factory processors registered as beans in the context. // call beanfactory's post-processor. These post-processors are invokebeanfactorypostprocessors (beanfactory) registered to the container in the bean definition; // register bean processors that intercept bean creation. // register the bean's post-processor. During bean creation, registerbeanpostprocessors (beanfactory) is called; // initialize message source for this context. // initialize initmessagesource () for the message source in the context; // initialize event multicaster for this context. // initialize the event mechanism initapplicationeventmulticaster () in the Context; // initialize other special beans in specific context subclasses. // initialize other special bean onrefresh (); // check for listener beans and register them. // check the listening beans and register these beans with the container registerlisteners (); // instantiate all remaining (non-Lazy-init) singletons. // instantiate all (non-Lazy-init) Singleton finishbeanfactoryinitialization (beanfactory); // last step: publish corresponding event. // release the container event and end the refresh process finishrefresh ();} catch (beansexception ex) {// destroy already created singletons to avoid dangling resources. destroybeans (); // reset 'active' flag. cancelrefresh (Ex); // propagate exception to caller. throw ex ;}}}

** 1.1: Container acquisition and data parsing Portal: obtainfreshbeanfactory () specific implementation refreshbeanfactory () left to subclass implementation
(Because abstractapplicationcontext is the specific general resource preparation, the specific interest-bearing read rule should be implemented by the sub-classes of each branch ):
Abstractrefreshableapplicationcontext --- refreshbeanfactory

@ Override protected final void refreshbeanfactory () throws beansexception {// here, if beanfactory has been created, destroy and close the beanfactory if (hasbeanfactory () {destroybeans (); closebeanfactory ();} // here is the place where the ultlistablebeanfactory is created and set and the loadbeandefinitions (beanfactory) is called at the same time to load beandefinition information. Try {defalistlistablebeanfactory beanfactory = createbeanfactory (); beanfactory. setserializationid (GETID (); // configure mimizebeanfactory (beanfactory), loadbeandefinitions (beanfactory), and synchronized (this. beanfactorymonitor) {This. beanfactory = beanfactory;} catch (ioexception ex) {Throw new applicationcontextexception ("I/O error parsing bean Definition source for" + getdisplayname (), Ex );}}

* ** 1.1.1: note that beanfactory -- defaultlistablebeanfactory will be used in the future:

Protected defaultlistablebeanfactory createbeanfactory () {(that is, the bucket is provided by the beanfactory branch instead of applicationcontext) return New defalistlistablebeanfactory (getinternalparentbeanfactory ());}

* *** 1.1.1.1: After being created, the variable assigned to abstractrefreshableapplicationcontext is:

/** Bean factory for this context */private DefaultListableBeanFactory beanFactory;

* *** 1.1.1.2: and implements the method for obtaining the abstractapplicationcontext declaration:

@Overridepublic final ConfigurableListableBeanFactory getBeanFactory() {synchronized (this.beanFactoryMonitor) {if (this.beanFactory == null) {throw new IllegalStateException("BeanFactory not initialized or already closed - " +"call 'refresh' before accessing beans via the ApplicationContext");}return this.beanFactory;}}

* *** 1.1.1.3: Synchronous lock:

/** Synchronization monitor for the internal BeanFactory */private final Object beanFactoryMonitor = new Object();

* ** 1.1.2 load the original encapsulated data of the parsing Bean: beandefinitions -- loadbeandefinitions (beanfactory)
The read tool class (xmlbeandefinitionreader) and execution parsing portal are specified here. Because our configuration can be in multiple forms. here we need to implement the specific resource form subclass (abstractxmlapplicationcontext.
Abstractxmlapplicationcontext:

@Overrideprotected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {// Create a new XmlBeanDefinitionReader for the given BeanFactory.XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);// Configure the bean definition reader with this context's// resource loading environment.beanDefinitionReader.setEnvironment(this.getEnvironment());beanDefinitionReader.setResourceLoader(this);beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));// Allow a subclass to provide custom initialization of the reader,// then proceed with actually loading the bean definitions.initBeanDefinitionReader(beanDefinitionReader);loadBeanDefinitions(beanDefinitionReader);}

* *** 1.1.2.1 The value of the application environment here is from the Super (parent) in the filesystemxmlapplicationcontext constructor at the beginning, calling the parent class constructor all the way, and finally
Implementation in abstractapplicationcontext:

public AbstractApplicationContext(ApplicationContext parent) {this.parent = parent;this.resourcePatternResolver = getResourcePatternResolver();this.environment = this.createEnvironment();}/** * Create and return a new {@link StandardEnvironment}. * <p>Subclasses may override this method in order to supply * a custom {@link ConfigurableEnvironment} implementation. */protected ConfigurableEnvironment createEnvironment() {return new StandardEnvironment();}

* *** 1.1.2.2resourceloader is obtained through inheritance (abstractapplicationcontext extends defaultresourceloader)

* *** 1.1.2.3entityresolver: allow the application to resolve external entities.
Using the following two constants, we can guess to read the format specification.

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";public DelegatingEntityResolver(ClassLoader classLoader) {this.dtdResolver = new BeansDtdResolver();this.schemaResolver = new PluggableSchemaResolver(classLoader);}...}

* *** 1.1.2.4 after preparing various required resources for xmlbeandefinitionreader, the actual parsing starts:
Here is the resource that we previously assigned to facilitate reading:

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {Resource[] configResources = getConfigResources();if (configResources != null) {reader.loadBeanDefinitions(configResources);}String[] configLocations = getConfigLocations();if (configLocations != null) {reader.loadBeanDefinitions(configLocations);}}

* ******** 1.1.2.4.1 is currently mainly the following string [] array.
The value assignment is performed in the abstractrefreshableconfigapplicationcontext (this is why we have added the abstractrefreshableconfigapplicationcontext parameter to the abstractrefreshableconfigapplicationcontext parameter, which extracts and encapsulates the resource assignment form separately ):

public void setConfigLocations(String[] locations) {if (locations != null) {Assert.noNullElements(locations, "Config locations must not be null");this.configLocations = new String[locations.length];for (int i = 0; i < locations.length; i++) {this.configLocations[i] = resolvePath(locations[i]).trim();}}else {this.configLocations = null;}}

This method is called in the filesystemxmlapplicationcontext constructor above.
(So here, we can see that there are a lot of different places and different forms of value assignment. These values will play their respective roles in future parsing and other processes)

Here, the applicationcontext's parsing work has come to an end, and then how xmlbeandefinitionreader parses it:
Many environment conditions have been prepared and calculated above, and then the next step is how to parse the XML into the initial bean type beandefinition.

============================================ ====================================
1. At first, it was a series of abstractbeandefinitionreader processing. After doing what he could do, he handed it over to the parent class, that is, the xmlbeandefinitionreader specified above.
2. xmlbeandefinitionreader also made a series of judgments. In the doloadbeandefinitions method, the loaddocument of defadocumentdocumentloader was called to obtain the document.
3. Then, some resources and documents are passed to defaultbeandefinitiondocumentreader. defabebeandefinitiondocumentreader does some work between reader and pure document parsing, including parsing and determining the trend.
4. Then, through beandefinitionparserdelegate, beandefinitionparserdelegate only receives the element and resolves the beandefinitionholder rule.
5. Finally, we use beandefinitionreaderutils to annotate our parsed beandefinition into our container defaultlistablebeanfactory.

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.