The whole process of instantiating a bean is as follows:
:
Where Beandefinition is added to the registry and processed by the Beanfactorypostprocessor implementation class, it needs to be instantiated by Instantiationstrategy. An instantiation is simply a call to a constructor, which is equivalent to a new object, and the specific properties of the bean are not assigned at this time (of course, the value of the bean attribute is initially configured in the XML, or if there is an assignment in the constructor, the related property is valued at the time of instantiation.) )。 Instantiationstrategy is responsible for instantiating the bean by default constructor, parameter constructor, or factory method of the Bean class. Here's instantiation.
The inheritance structure of the strategy (note that the following is the parent class, above the subclass, the solid line is inheritance, and the dashed lines are implemented):
Instantiationstrategy is just a strategic interface.
Simpleinstantiationstrategy is the Instantiationstrategy implementation class, which is a simple class for bean instantiation, such as the default constructor of the Bean class, The bean is instantiated with a parameter constructor or a factory method. As can be seen, the class has a Instantiationwithmethodinjection method, but in fact it is just a hook, not really support the method injection function.
Method injection: In most cases, the bean in the container is of type singleton (default), and the singleton type is that spring only instantiates the bean once and puts the bean into the buffer pool, returning the Bean's Reference (address) to the caller. If a singleton bean is to reference another singleton bean, or if a prototype bean references another prototype bean, It is usually possible to define a bean as the property value of another bean. Just like this:
<bean id= "Boss" class= "Com.baobaotao.attr.Boss" > <property name= "Car" > <ref parent= "Car"/ > </property> </bean>
This can be problematic for beans with different lifecycles, for example, when invoking a method of a singleton type bean A, you need to refer to the bean B of another prototype type (which will re-instantiate the bean each time it is called), for Bean a , the container is created only once, so it is not necessary to have the container give bean a a new instance of Bean B every time it is needed. That is, every time I call a, I need a re-instantiation of B. And since a is only instantiated once, and B is instantiated with the instantiation of a, the b I get is not instantiated again. This is the time to use method injection. To give a simple example:
1 <bean id= "car" class= "Com.baobaotao.injectfun.Car" 2 p:brand= "Red flag CA72" p:price= "$" scope= "prototype"/> 3 4 <bean id= "Magicboss" class= "Com.baobaotao.injectfun.MagicBoss" >5 <lookup-method name= "Getcar" bean= "Car"/>6 </bean>
Use the Lookup-method tag so that the Getcar method is loaded each time the Magicboss is instantiated, as follows:
Public interface Magicboss { Car getcar ();}
Because bean= "car" is defined inside the Lookup-method, Spring automatically instantiates car. It is equivalent to writing a method of instantiating car in Getcar ().
The real support for the method injection function is the Simpleinstantiationstrategy inheritance class: Cglibsubclassinginstantiationstrategy. It inherits the Simpleinstantiationstrategy and overrides the Instantiationwithmethodinjection method. However, the Cglib class library must be used for this method. It uses Cglib to dynamically generate subclasses for beans, which are called proxy classes, generate the logic of method injection in subclasses, and then use this dynamically generated subclass to create an instance of the bean. (Learn more about this technology, learn about spring's AOP, programming for facets.) I'll talk about it in detail later in the chapter).
Here's a look at the instantiate method of the default called Simpleinstantiationstrategy:
1 PublicObject Instantiate (rootbeandefinition beandefinition, String beanname, beanfactory owner) {2 //Don ' t override the class with CGLIB if no overrides.3 if(Beandefinition.getmethodoverrides (). IsEmpty ()) {4Constructor<?>Constructortouse;5 synchronized(beandefinition.constructorargumentlock) {6Constructortouse = (constructor<?>) Beandefinition.resolvedconstructororfactorymethod;7 if (constructortouse = = null) { 8 FinalClass Clazz =Beandefinition.getbeanclass ();9 if(Clazz.isinterface ()) {Ten Throw NewBeaninstantiationexception (Clazz, "Specified class is an interface"); One } A Try { - if(System.getsecuritymanager ()! =NULL) { -Constructortouse = accesscontroller.doprivileged (NewPrivilegedexceptionaction<constructor>() { the PublicConstructor Run ()throwsException { - returnClazz.getdeclaredconstructor ((class[])NULL); - } - }); + } - Else { + Constructortouse = Clazz.getdeclaredconstructor ((class[]) null); A } atBeandefinition.resolvedconstructororfactorymethod =Constructortouse; - } - Catch(Exception ex) { - Throw NewBeaninstantiationexception (Clazz, "No default constructor found", ex); - } - } in } - return beanutils.instantiateclass (constructortouse); to } + Else { - //must generate CGLIB subclass. the returninstantiatewithmethodinjection (beandefinition, Beanname, owner); * } $}
Since the pre-post will not be too much to talk about the source code, so just about to understand, from lines 7th and 21st can be seen: if the bean does not have its own constructor, then use the reflection mechanism to invoke the default parameterless constructor to instantiate the bean. Finally, 30 lines, get this constructor, execute the Beanutils.instantiateclass method. Here is the method:
1 Public Static<T> T Instantiateclass (constructor<t> ctor, Object ... args)throwsbeaninstantiationexception {2Assert.notnull (ctor, "Constructor must not is null");3 Try { 4 reflectionutils.makeaccessible (ctor); 5 return ctor.newinstance (args); 6 }7 Catch(Instantiationexception ex) {8 Throw Newbeaninstantiationexception (Ctor.getdeclaringclass (),9"Is it an abstract class?", ex);Ten } One Catch(Illegalaccessexception ex) { A Throw Newbeaninstantiationexception (Ctor.getdeclaringclass (), -"Is the constructor accessible?", ex); - } the Catch(IllegalArgumentException ex) { - Throw Newbeaninstantiationexception (Ctor.getdeclaringclass (), -"Illegal arguments for constructor", ex); - } + Catch(InvocationTargetException ex) { - Throw Newbeaninstantiationexception (Ctor.getdeclaringclass (), +"Constructor threw exception", Ex.gettargetexception ()); A } at}
Row four and line fifth create an instance (you first need to make the resulting constructor strong to be accessible).
A bean instantiated by Instantiationstrategy is just equivalent to generating a new object, and the assignment of a property is also done by Beanwrapper with the property editor. The Beanwrapper and property editors will be described in detail in the next blog post.
Learning without knowing, with not learning, knowing and not doing, and not knowing the same.
--Huang 睎
(spring-10th back to "IOC Basics") instantiationstrategy--the third big weapon for instantiating beans