Spring Bean Source Simple parsing

Source: Internet
Author: User

Recently in the spring source, found to see this or a little early, look very hard, there are many things are not very clear, such as agents,

I feel that spring uses the abstract template to write the main functions, with the interface to expand the function, with the superb, but also let a lot of simple

Things become less understood, is to write the wordy, personal feeling. Below is the following spring Bean source learning:

private static final Resource Returns_null_context = Qualifiedresource (CLASS, "returnsnull.xml");

Defaultlistablebeanfactory factory = new Defaultlistablebeanfactory (); New Xmlbeandefinitionreader (Factory). Loadbeandefinitions (returns_null_context); Object result = Factory.getbean ("Factorybean");

This is the entire spring bean source code to do the entire parsing, but the overall, basically three steps:

1: Load XML, encapsulated as resource object.

2: Parse XML file, the related attributes put to beandefinition, and put beandefinition into Beanfactory, actually is beandefinitionmap.

3: Inject the object through the Getbean ("Factorybean") method.

Here's a straight-point thing:

From this directory structure is not difficult to see the specific idea of the whole project, not specifically the role of each class and interface, the following specific load parse the entire process of XML:

/** * Load Bean definitions from the specified XML file. * @param resource The Resource descriptor for the XML file * @return The number of beans definitions found * @throws Beande Finitionstoreexception in case of loading or parsing errors */public int loadbeandefinitions (Resource Resource) throws Bea ndefinitionstoreexception {return loadbeandefinitions (new Encodedresource (Resource));}

public int loadbeandefinitions (Encodedresource encodedresource) throws Beandefinitionstoreexception {    InputStream InputStream = Encodedresource.getresource (). getInputStream ();            try {inputsource InputSource = new InputSource (InputStream);            if (encodedresource.getencoding () = null) {inputsource.setencoding (encodedresource.getencoding ());        }  return Doloadbeandefinitions (InputSource, Encodedresource.getresource ()); }}
The second piece of code is too long, not intuitive, only a key part, from the above is not difficult to see, specifically done 3 parts:

1: Package Resource resources,

2: Get input stream

3: Call Doloadbeandefinitions (InputSource, Encodedresource.getresource ()) method, i.e. parse


/** * Actually load bean definitions from the specified XML file.  * @param inputsource the SAX inputsource to read from * @param resource the Resource descriptor for the XML file * @return The number of beans definitions found * @throws beandefinitionstoreexception in case of loading or parsing err ORS */protected int Doloadbeandefinitions (InputSource inputsource, Resource Resource) throws Beandefinitionstoreexcept Ion {    try {int validationmode = Getvalidationmodeforresource (Resource);D ocument doc = This.documentLoader.loadDocument (    InputSource, Getentityresolver (), This.errorhandler, Validationmode, Isnamespaceaware ()); return Registerbeandefinitions (Doc, Resource);}    }
This code also only intercepts some of the key code, specifically said three meaning:

1: Get XML validation modulo mode

2: Get Document Object

3: Register

The registration here is mainly to have all the properties of beandefinition into the map, here is probably the majority of the less clear, I personally think.


/** * Register The bean definitions contained in the given DOM document.     * Called by {@code loadbeandefinitions}.     * <p>creates A new instance of the parser class and invokes * {@code registerbeandefinitions} on it. * @param doc the DOM document * @param resource the Resource descriptor (for context information) * @return the Nu Mber of beans Definitions found * @throws beandefinitionstoreexception in case of parsing errors * @see #loadBeanDe Finitions * @see #setDocumentReaderClass * @see beandefinitiondocumentreader#registerbeandefinitions * * Pub LIC int registerbeandefinitions (Document doc, Resource Resource) throws Beandefinitionstoreexception {Beandefiniti        Ondocumentreader Documentreader = Createbeandefinitiondocumentreader ();        Documentreader.setenvironment (Getenvironment ());        int countbefore = GetRegistry (). Getbeandefinitioncount (); Documentreader.registerbeandefinitions (Doc, Createreadercontext (RESOURCe));    Return GetRegistry (). Getbeandefinitioncount ()-Countbefore; }

The main point here is to use Beandefinitiondocumentreader to register, analytic work.


/** * This implementation parses beans definitions according to the "Spring-beans" XSD * (or DTD, historically). * <p>opens a DOM Document; Then initializes the default settings * specified on the {@code <beans/>} level; Then parses the contained bean definitions. */public void Registerbeandefinitions (Document doc, Xmlreadercontext readercontext) {This.readercontext = Readercontext;logger.debug ("Loading bean Definitions"); Element root = doc.getdocumentelement ();d oregisterbeandefinitions (root);}

/** * Register Each bean definition within the given root {@code <beans/>} element. */protected void doregisterbeandefinitions (Element root) {String Profilespec = Root.getattribute (Profile_attribute); if (Stringutils.hastext (Profilespec)) {string[] specifiedprofiles = Stringutils.tokenizetostringarray (ProfileSpec, Beandefinitionparserdelegate.multi_value_attribute_delimiters); if (!getenvironment (). AcceptsProfiles ( Specifiedprofiles)) {return;}} Any nested <beans> elements would cause recursion in this method. in//order to propagate and preserve <beans> default-* attributes correctly,//keep track of the current (parent) de Legate, which may be null. create//the new (child) delegate with a reference to the parent for fallback purposes,//then ultimately reset This.deleg Ate back to it original (parent) reference.//This behavior emulates a stack of delegates without actually necessitating One. Beandefinitionparserdelegate parent = This.delegate;this.delegate = CreatedelEgate (This.readercontext, root, parent);p Reprocessxml (Root);p arsebeandefinitions (root, this.delegate); Postprocessxml (root); this.delegate = parent;}

/** * Parse The elements at the root level in the document: * "import", "Alias", "Bean". * @param root the DOM root element of the document */protected void Parsebeandefinitions (element root, Beandefinitionp  Arserdelegate delegate) {if (Delegate.isdefaultnamespace (root)) {NodeList nl = root.getchildnodes (); for (int i = 0; i < Nl.getlength (); i++) {Node node = Nl.item (i), if (Node instanceof Element) {element ele = (Element) node;if (Delegate.isdefaultnamespace (el e) {parsedefaultelement (ele, delegate);} else {delegate.parsecustomelement (ele);}}}} else {delegate.parsecustomelement (root);}}

These three pieces of code are relatively simple, and the last piece of code is to iterate through all the elements, like <bean/>. Here's the play, and here's what you got.

private void Parsedefaultelement (Element ele, beandefinitionparserdelegate delegate) {if (Delegate.nodenameequals (ele , import_element)) {Importbeandefinitionresource (ele);} else if (delegate.nodenameequals (Ele, alias_element)) {processaliasregistration (ele);} else if (delegate.nodenameequals (Ele, bean_element)) {processbeandefinition (ele, delegate);} else if (delegate.nodenameequals (Ele, nested_beans_element)) {//Recursedoregisterbeandefinitions (Ele);}}

/** * Process The given bean element, parsing the bean definition * and registering it with the registry. */protected void Processbeandefinition (Element ele, beandefinitionparserdelegate delegate) {Beandefinitionholder Bdholder = Delegate.parsebeandefinitionelement (ele); if (bdholder! = null) {Bdholder = Delegate.decoratebeandefinitionifrequired (Ele, bdholder); try {//Register the final decorated instance. Beandefinitionreaderutils.registerbeandefinition (Bdholder, Getreadercontext (). GetRegistry ());} catch (Beandefinitionstoreexception ex) {Getreadercontext (). Error ("Failed to register bean definition with name '" +bdhol Der.getbeanname () + "'", Ele, ex);} Send registration Event.getreadercontext (). firecomponentregistered (New Beancomponentdefinition (BdHolder));}}

/** * Parses the supplied {@code <bean>} element. May return {@code null} * If there were errors during parse. Errors is reported to the * {@link org.springframework.beans.factory.parsing.ProblemReporter}. */public beandefinitionholder parsebeandefinitionelement (Element ele, beandefinition containingbean) {String id = Ele.getattribute (Id_attribute); String nameattr = Ele.getattribute (Name_attribute); list<string> aliases = new arraylist<string> (); if (Stringutils.haslength (nameattr)) {string[] NameArr = Stringutils.tokenizetostringarray (nameattr, multi_value_attribute_delimiters); Aliases.addall (Arrays.asList ( Namearr));} String beanname = id;if (! Stringutils.hastext (beanname) &&!aliases.isempty ()) {beanname = Aliases.remove (0); if (logger.isdebugenabled ()) {Logger.debug ("No XML ' id ' specified-using '" + beanname + "' as Bean name and" + aliases + "as aliases");}} if (Containingbean = = null) {checknameuniqueness (beanname, aliases, ele);} Abstractbeandefinition BeaNdefinition = Parsebeandefinitionelement (Ele, Beanname, Containingbean); if (beandefinition! = null) {if (! Stringutils.hastext (Beanname)) {try {if (Containingbean! = null) {Beanname = Beandefinitionreaderutils.generatebeanname (Beandefinition, This.readerContext.getRegistry (), true);} else {beanname = This.readerContext.generateBeanName (beandefinition);//Register an alias for the plain Bean class name, I F still possible,//if the generator returned the class name plus a suffix.//this was expected for Spring 1.2/2.0 backward s compatibility. String beanclassname = Beandefinition.getbeanclassname (); if (beanclassname! = null &&beanname.startswith ( Beanclassname) && beanname.length () > Beanclassname.length () &&!this.readercontext.getregistry () . Isbeannameinuse (Beanclassname)) {Aliases.add (beanclassname);}} if (logger.isdebugenabled ()) {Logger.debug ("Neither XML ' id ' nor ' name ' specified-" + "using generated bean name [" + Bea Nname + "]");}} catch (Exception ex) {error (EX.getmessage (), ele); return null;}} string[] Aliasesarray = Stringutils.tostringarray (aliases); return new Beandefinitionholder (Beandefinition, BeanName, Aliasesarray);} return null;}

/** * Parse The bean definition itself, without regard to name or aliases. May return * {@code null} If problems occurred during the parsing of the bean definition. */public abstractbeandefinition parsebeandefinitionelement (Element ele, String beanname, beandefinition Containingbean) {This.parseState.push (new Beanentry (Beanname)); String className = null;if (Ele.hasattribute (Class_attribute)) {className = Ele.getattribute (Class_attribute). Trim (); try {String parent = null;if (Ele.hasattribute (Parent_attribute)) {parent = Ele.getattribute (Parent_attribute);} abstractbeandefinition bd = Createbeandefinition (className, parent);p arsebeandefinitionattributes (Ele, Beanname, Containingbean, BD); Bd.setdescription (Domutils.getchildelementvaluebytagname (Ele, description_element)); Parsemetaelements (Ele, BD);p arselookupoverridesubelements (Ele, Bd.getmethodoverrides ()); Parsereplacedmethodsubelements (Ele, Bd.getmethodoverrides ());p arseconstructorargelements (Ele, BD); Parsepropertyelements (Ele, BD);p ARSEqualifierelements (Ele, BD); Bd.setresource (This.readerContext.getResource ()); Bd.setsource (Extractsource (ele)); return BD;} catch (ClassNotFoundException ex) {error ("Bean class [" + ClassName + "] not found", Ele, ex);} catch (Noclassdeffounderror Err) {error ("class that Bean class [" + ClassName + "] depends on not found", ele, err);} catch (Throwable ex) {error ("Unexpected failure during bean definition parsing", ele, ex);} finally {This.parseState.pop ();} return null;}

Here the main id,name,class, such as the interpretation of attributes. That is, the attribute is injected into the beandefinition, and finally placed in the map.

This is just the whole process, I did not read the details, I feel I hit the breakpoint more than a few times more practical point. These things are just my personal understanding,

There is no place to wish to point out, thank you here.

The injection of the object is mainly abstractautowirecapablebeanfactory this class to operate. This article is not much to say, the next article and we discuss.











Spring Bean Source Simple parsing

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.