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