Spring IOC source code interpretation--Talk about several states of bean

Source: Internet
Author: User

Read the spring IOC part of the source code for some time, through continuous single-step debugging and reference materials, the spring container bean management has a certain understanding. From the point of view of several states of beans, this paper studies the IOC container.

First, raw materials

The bean definition configuration (or annotations) in XML, and Java code

    <BeanID= "book"name= "book"class= "Com.sky.vo.Book"Scope= "Singleton"Init-method= "Productbook"Destroy-method= "Destroybook">        < Propertyname= "title"value= "The Little Prince"/>    </Bean>
 Public class Implements Initializingbean, Disposablebean, Beanfactoryaware, applicationcontextaware{    private  String title;          Public Book () {        System.out.println ("called Book Default constructor");    }          Public void  Productbook () {        System.out.println ("book Initialization Init-method");    } ///.......}

Second, semi-finished products

Beandefinition is an important interface in spring, which is an abstraction of the bean (the simple understanding is that his attributes correspond to information such as attributes and child nodes defined in <bean>). He is a semi-finished product, so we will hardly use it directly, but circulate inside the IOC container!

Reading source discovery is parsing XML with sax and then saving it to the Beandefinition object. The following are the key pseudo-code

 /*  **beandefinitionparserdelegate.java  */ public   Abstractbeandefinition Parsebeandefinitionelement (Element ele, String beanname, Beandefinition Containingbean) {abstractbeandefinition bd  = Createbeandefinition (ClassName, parent) {genericbeandefinition bd  = new        Genericbeandefinition ();      Bd.setbeanclassname (ClassName);          return   BD;    } parsebeandefinitionattributes (Ele, Beanname, Containingbean, BD);    Parseconstructorargelements (Ele, BD);  Parsepropertyelements (Ele, BD);  //  omit code to parse other child nodes } 

The core parsing process is relatively simple, creating a genericbeandefinition, and then setting the node properties and <property>, <construct-arg>, and so on to his attributes.

Then there is a more critical step, that is, the timing and location of the converted Beandefinition storage, which is stored at the start of the spring IOC container, the specific code:

/***defaultlistablebeanfactory.java*/     Public voidregisterbeandefinition (String beanname, beandefinition beandefinition) {synchronized( This. Beandefinitionmap) {Object oldbeandefinition= This. Beandefinitionmap.get (Beanname); if(Oldbeandefinition! =NULL) {                if(! This. allowbeandefinitionoverriding) {                    Throw NewBeandefinitionstoreexception ("Cannot register bean definition for beans, there is already bound.")); }                Else {                     This. Logger.info ("Overriding bean definition for bean, replacing Oldbeandefinition"); }            }            Else {                 This. Beandefinitionnames.add (Beanname); }             This. Beandefinitionmap.put (Beanname, beandefinition); }}

You can see that the final store is in the beandefinitionmap map, to see his definition (Defaultlistablebeanfactory.java)

    Private Final New Concurrenthashmap<string, beandefinition> (64);

In this way, the spring container holds the beandefinition.

Third, the finished product

Getting the finished product is getting the specific bean object, which is actually the object bean = Beanfactroy.getbean (beanname). There are some differences depending on scope, in short:

A, Singleton is instantiated when the IOC container is initialized and cached to map; Getbean (Singletonbeanname) is taken from this map;

If singleton lazy-init= "true" at the same time, the first Getbean is cached to map and later taken from map;

B, Getbean (prototypebeanname), each time the new Bean object is instantiated;

1. Singleton Bean

Look directly at the pseudo-code (some key code is intercepted)

    //start with the GetbeanBeanfactroy.getbean ("Beanname") {abstractbeanfactory.createbean{Object beaninstance=Docreatebean (Beanname, mbd, args) {//eagerly check singleton cache for manually registered singletons. //This is the bean:[email that returned the cached singleton protected]Object sharedinstance =Getsingleton (beanname) {returnObject Singletonobject = This. Singletonobjects.get (Beanname); }                return(T) bean; }            }    }

From the source we can see, for singleton Bean, we directly from singletonobjects this map to take!

 Public class defaultsingletonbeanregistry{  /** caches singleton bean:beanname--->bean instance * / Private Final New Concurrenthashmap<string, object> (+);}  

So when did the bean instance deposit to this map? See the source know when the IOC container is started.

By analyzing the source code many times, we know that Abstractapplicationcontext.refresh () completes the process of initializing the container, and the instantiation of the Singleton Bean is done here.

     Public voidAbstractapplicationcontext.refresh () {//Create a spring containerConfigurablelistablebeanfactory beanfactory =obtainfreshbeanfactory (); //Instantiate all remaining (Non-lazy-init) singletons.abstractapplicationcontext.finishbeanfactoryinitialization (beanfactory) {defaultlistablebeanfactory . Preinstantiatesingletons () {rootbeandefinition bd=getmergedlocalbeandefinition (beanname); if(!bd.isabstract () && Bd.issingleton () &&!Bd.islazyinit ()) {                    //then, the Getbean operation is performed!!! The code executed here is the Beanfactory.getbean (beanname) SectionAbstractbeanfactory.getbean (beanname) {Abstractbeanfactory.dogetbean (Beanna Me) {//Cache is emptyObject sharedinstance =Getsingleton (beanname); //if it's singleton,                            if(Mbd.issingleton ()) {Defaultsingletonbeanregistry.getsingleton () { synchronized( This. Singletonobjects) {                                        //the cache is empty here.Object Singletonobject = This. Singletonobjects.get (Beanname); //instantiating BeansSingletonobject =Singletonfactory.getobject () {Object beaninstance=Docreatebean (Beanname, mbd, args); }                                        //It's very important here to put the instantiated bean in the mapAddsingleton (Beanname, Singletonobject) {  This. Singletonobjects.put (Beanname, (singletonobject! =NULL?singletonobject:null_object));                        }                                    }                                }                            } }                    }                }            }        }    }

Capturing some of the key snippets, you can see that the spring container initializes the instantiated singleton bean to the Singletonobject

Spring IOC source code interpretation--Talk about several states of bean

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.