Life cycle PlotsBecause the bean's life cycle experiences more stages, we will describe it in a graphical way. The following diagram depicts the complete process of the bean life cycle in Beanfactory:
The Bean's life cycle begins by instantiating the bean from the spring container, until the bean is eventually destroyed, which passes through many key points, each of which involves a call to a particular method, which can be roughly divided into 3 classes: (1) The Bean's own method: such as invoking the Bean constructor, Instantiate the bean, call the setter to set the Bean's property value and the method specified by the <bean> Init-method and Destroy-method; (2) bean-Level Lifecycle interface method: such as Beannameaware, Beanfactoryaware, Initializationbean, and Disposablebean, these interface methods are implemented directly by the Bean class, and (3) the container-level life-cycle interface method: As shown in the red section of the figure above, This interface is implemented by Instantiationawarebeanpostprocessor and Beanpostprocessor, which is generally called the "post processor" for their implementation class. The post-processor interface, which is generally not implemented by the bean itself, is independent of the bean, the implementation class is registered with the container add-on in the spring container, and is reflected by the interface to the spring container pre-identified. When the spring container creates any beans, these post-processors all work, so the impact of these post-processors is global. Of course, the user can write the post processor reasonably, so that it will only be processed by the bean of interest.
Instantiationawarebeanpostprocessor is actually a sub-interface of the Beanpostprocessor interface, defined in spring 1.2, An adapter class Instantiationawarebeanpostprocessoradapter is provided in Spring2.0, and in general it is easy to extend the adapter to cover the methods of interest to define the implementation class. Let's take a concrete example to better understand each step of the bean lifecycle.
An example of prying into the bean life cycleCar that implements various life cycle control access
Package com.spring.beanfactory;
Import org.springframework.beans.BeansException;
Import Org.springframework.beans.factory.BeanFactory;
Import Org.springframework.beans.factory.BeanFactoryAware;
Import Org.springframework.beans.factory.BeanNameAware;
Import Org.springframework.beans.factory.DisposableBean;
Import Org.springframework.beans.factory.InitializingBean;
public class Car implements beanfactoryaware,beannameaware,initializingbean,disposablebean{private String brand;
private String color;
private int maxspeed;
Private Beanfactory beanfactory;
Private String Beanname;
Public String GetColor () {return color;
The public void SetColor (String color) {this.color = color;
} public int Getmaxspeed () {return maxspeed;
} public void Setmaxspeed (int maxspeed) {this.maxspeed = Maxspeed;
} public String Getbrand () {return brand;
} public beanfactory Getbeanfactory () {return beanfactory;
} public String Getbeanname () {return beanname; }//1, tubeThe interface of the Bean life Cycle public Car () {System.out.println ("Call car constructor");
} public void Setbrand (String brand) {System.out.println ("Call Setbrand () set property");
This.brand = brand;
} public void introduce () {System.out.println ("BRADN: +brand+"; color "+color+"; Maxspeed: "+maxspeed"); }//2, Beanfactoryaware interface method public void Setbeanfactory (Beanfactory beanfactory) throws Beansexception {System.ou
T.println ("Call Beanfactoryaware.setbeanfactory ()");
This.beanfactory=beanfactory; }//3, Beannameaware interface method public void Setbeanname (String beanname) {System.out.println ("Call Beannameaware.setbeanna
Me () ");
This.beanname=beanname; }//4 Nitializingbean interface method public void Afterpropertiesset () throws Exception {System.out.println ("Call Initializin
Gbean.afterpropertiesset () "); }//5 Disposablebean interface method public void Destroy () throws Exception {System.out.println ("Call Disposablebean.destroy (
)");
}//6 The initialization method specified by the Init-method property of <bean> public void Myinit () { SYSTEM.OUT.PRINTLN ("Call the Myinit () specified by Inti-method, set the maxspeed to 240.");
this.maxspeed=240; The Destroy method specified by the Destory-method property of the <bean>//7 public void Mydestory () {System.out.println ("Call Destory-met The Mydestory () method specified by the Hod.
"); }
}
Instantiationawarebeanpostprocessor Implementation Class
Package com.spring.beanfactory;
Import Java.beans.PropertyDescriptor;
Import org.springframework.beans.BeansException;
Import org.springframework.beans.PropertyValues;
Import Org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
@SuppressWarnings ("Unchecked") public class Myinstantiationawarebeanpostprocessor extends Instantiationawarebeanpostprocessoradapter {//1 interface method: Calling public Object postprocessbeforeinstantiation before instantiating the bean (Cla SS Beanclass,string Beanname) throws Beansexception {//1-1 only handles Car-bean in the container if ("Car". Equals (Beanname)) {Syst
Em.out.println ("Instantiationawarebeanpostprocessor.postprocessbeforeinstantiation ()");
} return null; //2 interface method: Call public after instantiating a bean Boolean postprocessafterinstantiation (Object bean, String beanname) throws Beansexce ption{if ("Car". Equals (Beanname)) {System.out.println ("Instantiationawarebeanpostprocessor.postprocessafterinst
Antiation () ");
} return true; //3 interface Method: Call public propertyvalues postprocesspropertyvalues when setting a property (Propertyvalues propertyvalues, Propert Ydescriptor apropertydescriptor[], Object Bean, String beanname) throws beansexception{//3-1 only handles Car-bean in the container and can Filter by post entry,//only a specific property of car is processed if ("Car". Equals (Beanname)) {System.out.println ("Instantia
Tionawarebeanpostprocessor.postprocesspropertyvalues ");
} return propertyvalues; }
}
Beanpostprocessor Implementation Class
Package com.spring.beanfactory;
Import org.springframework.beans.BeansException;
Import Org.springframework.beans.factory.config.BeanPostProcessor;
public class Mybeanpostprocessor implements Beanpostprocessor {public
Object postprocessbeforeinitialization ( Object Bean, String beanname)
throws beansexception {
if (beanname.equals ("Car")) {
car car= (car) bean;
if (Car.getcolor () ==null) {
System.out.println ("Call Beanpostprocessor.postprocessbeforeinitialization (), Color is blank, set to default black. ");
Car.setcolor ("Black");
}
}
return bean;
}
public object Postprocessafterinitialization (object bean, String beanname)
throws beansexception {
if ( Beanname.equals ("Car")) {
car car= (car) bean;
if (Car.getmaxspeed () >=200) {
System.out.println ("Call Beanpostprocessor.postprocessafterinitialization (), Adjust the maxspedd to A. ");
Car.setmaxspeed (+);
}
}
return bean;
}
}
Defining the car's configuration information in the spring configuration file
<?xml version= "1.0" encoding= "UTF-8"?> <beans
xmlns= "Http://www.springframework.org/schema/beans"
xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xmlns:p= "http://www.springframework.org/schema/ P "
xsi:schemalocation=" Http://www.springframework.org/schema/beans
http://www.springframework.org/ Schema/beans/spring-beans-3.0.xsd ">
<bean id=" car "class=" Com.spring.beanfactory.Car "init-method= "Myinit" destroy-method= "mydestory"
p:brand= "Red flag CA72"
p:maxspeed= ""
scope= [
Singleton]/>
</beans>
Below we let the container load the configuration file and then separately register the two post processors provided above:
Package com.spring.beanfactory;
Import Org.springframework.beans.factory.BeanFactory;
Import Org.springframework.beans.factory.config.ConfigurableBeanFactory;
Import Org.springframework.beans.factory.xml.XmlBeanFactory;
Import Org.springframework.core.io.ClassPathResource;
Import Org.springframework.core.io.Resource; public class Beanlifecycle {private static void Lificycleinbeanfactory () {//1 The following two sentences load the configuration file and start the container Resource res=new
Classpathresource ("Beans.xml");
Beanfactory bf=new xmlbeanfactory (res);
2 Register the Mybeanpostprocesser processor ((configurablebeanfactory) BF) with the container. Addbeanpostprocessor (New Mybeanpostprocessor ()); 3 Register the Myinstantiationawarebeanpostprocessor Post processor ((configurablebeanfactory) BF) into the container. Addbeanpostprocessor (New
Myinstantiationawarebeanpostprocessor ());
4 first gets the car from the container, the penalty container instantiates the bean, which throws a call to the bean life cycle method of car car1= (car) bf.getbean ("Car");
Car1.introduce ();
Car1.setcolor ("Red"); 5 The second time get car from the container, take it directly from the cache pool (because scope= "singleton") Car car2 = (car) bf.getbean ("Car");
6 See if Car1 and Car2 point to the same reference System.out.println ("Car1==car2" + (CAR1==CAR2));
7 Close the container ((xmlbeanfactory) BF). Destroysingletons ();
} public static void Main (string[] args) {lificycleinbeanfactory (); }
}
After running, the results are as follows:
March 27, 2014 11:16:39 am org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadbeandefinitions Info: Loading
XML Bean definitions from class path resource [Beans.xml]
Instantiationawarebeanpostprocessor.postprocessbeforeinstantiation () Call car constructor
Instantiationawarebeanpostprocessor.postprocessafterinstantiation ()
Instantiationawarebeanpostprocessor.postprocesspropertyvalues call Setbrand () to set the property call Beannameaware.setbeanname ()
Call Beanfactoryaware.setbeanfactory () call beanpostprocessor.postprocessbeforeinitialization (), color is empty, set to default black.
Call Initializingbean.afterpropertiesset () to call the Myinit () specified by Inti-method and set the Maxspeed to 240.
Call Beanpostprocessor.postprocessafterinitialization () and adjust the Maxspedd to 200. BRADN: Red Flag ca72;color black; maxspeed:200 Car1==car2true March 27, 2014 11:16:39 am Org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroysingletons Info: Destroying singletons In org.springframework.beans.factory.xml.xmlbeanfactory@1ed7c33:defining beans [car]; Root of factory hierarchy call dispOsablebean.destroy () invokes the Mydestory () method specified by Destory-method.
Careful observation of the output information will reveal that it validates the life cycle process we described earlier. At 7, we closed the container through the Destroysingletons () method, because the car implements the destroy interface and specifies the Destroy method, so the container will trigger the invocation of both methods.
the life cycle of beans in ApplicationContextThe Bean's life cycle in the context of the application is similar to the life cycle in the beanfactory, unlike the If the bean implements the Org.springframework.context.ApplicationContext interface, it adds a method Setapplicationcontext () step that invokes the interface. This method is immediately followed by Beanfactoryaware, and if the implementation class of the factory post processor interface Beanfactorypostprocessor is declared in the configuration file, the application context after the configuration file is loaded, These beanfactorypostprocessor are called before the bean instance is initialized to process the configuration information.
Another big difference between ApplicationContext and Beanfactory is that the former uses the Java mechanism to automatically identify the beanpostprocessor defined in the configuration file. Instantiationawarebeanpostprocessor and Beanfactorypostprocessor, and automatically register them in the app context , and the latter needs to be registered in code by calling the Addbeanpostprocessor () method manually. This is one of the reasons why we generally use applicationcontext and seldom use beanfactory in application development. In ApplicationContext, we only need to define the factory post processor and the Bean post processor in the configuration file by <bean>, and they will execute as expected.
To see an example of using a factory post processor, let's say we want to tweak the brand configuration property of car in the configuration file, you can write a post-factory processor like this:
Factory Post Processor: Mybeanfactoypostprocessor.java
Package com.spring.context;
Import org.springframework.beans.BeansException;
Import org.springframework.beans.factory.config.BeanDefinition;
Import Org.springframework.beans.factory.config.BeanFactoryPostProcessor;
Import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
Import Org.springframework.context.annotation.Bean;
public class Mybeanfactoypostprocessor implements beanfactorypostprocessor{
//1 to Car<bean> The Brand property configuration information for "Rescue" processing operation public
void Postprocessbeanfactory (
configurablelistablebeanfactory BF)
Throws Beansexception {
beandefinition bd=bf.getbeandefinition ("car");
Bd.getpropertyvalues (). Addpropertyvalue ("brand", "Chery QQ");
System.out.println ("Call Beanfactorypostprocessor.postprocessbeanfactory ()!");
}
}
ApplicationContext at startup, a Beandefinition object is generated first for each <bean> in the configuration file, and beandefinition is the internal representation of <bean> in the spring container. When all <bean> in a configuration file is parsed into a definition, ApplicationContext will call the factory post-processor method, so we have the opportunity to adjust the bean configuration information programmatically. Here, we will adjust the car's beandefinition, the brand property set to "Chery QQ", the following is the specific configuration: Beans.xml
<?xml version= "1.0" encoding= "UTF-8"?> <beans xmlns= "http://www.springframework.org/ Schema/beans "xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance "xmlns:p=" http://www.springframework.org/ schema/p "xsi:schemalocation=" Http://www.springframework.org/schema/beans http://www.springframework.or G/schema/beans/spring-beans-3.0.xsd "> <!--1 The value of this brand property will be replaced by the factory post processor--<bean id=" car "class=" Com.sprin G.beanfactory.car "init-method=" Myinit "destroy-method=" mydestory "p:brand=" Red Flag CA72 "p:maxspeed="/>
;
<!--2 Bean after processor--<bean id= "Mybeanpostprocessor" class= "Com.spring.beanfactory.MyBeanPostProcessor"/> <!--3 Bean factory post processor--<bean id= "mybeanfactory" class= "Com.spring.context.MyBeanFactoyPostProcessor"/> &L T;/beans>
The beanpostprocessor and Beanfactorypostprocessor defined at 2 and 3 are automatically recognized and registered in the container by ApplicationContext. 3 Registered factory Post processors will adjust the value of the 1 configured properties. At 2, we also define a bean post processor, which can also be adjusted for the properties configured at 1. Starting the container and looking at the car bean's information, we will find that the car bean's brand property was successfully modified by the factory post processor.
Package com.spring.test;
Import Org.springframework.context.ApplicationContext;
Import Org.springframework.context.support.ClassPathXmlApplicationContext;
Import Com.spring.beanfactory.Car;
public class Test {public
static void Main (string[] args) {
ApplicationContext ctx=new Classpathxmlapplicationcontext ("Beans.xml");
Car car = (car) ctx.getbean ("Car");
System.out.println (Car.getbrand ());
}
}
The output information is as follows:
March 27, 2014 1:55:54 pm org.springframework.context.support.AbstractApplicationContext Preparerefresh Info: Refreshing Org.springframework.context.support.classpathxmlapplicationcontext@17f1841:startup Date [Thu Mar 13:55:54 CST 2014 ]; Root of the context hierarchy March 27, 2014 1:55:54 pm Org.springframework.beans.factory.xml.XmlBeanDefinitionReader Loadbeandefinitions info: Loading XML Bean Definitions from class path resource [Beans.xml] Call Beanfactorypostprocessor.post
Processbeanfactory ()!
March 27, 2014 1:55:54 pm org.springframework.beans.factory.support.DefaultListableBeanFactory preinstantiatesingletons Information: pre-instantiating singletons in org.springframework.beans.factory.support.defaultlistablebeanfactory@16fb592: defining beans [car,mybeanpostprocessor,mybeanfactory]; Root of factory hierarchy calls the car constructor call Setbrand () to set the property call Beannameaware.setbeanname () call Beanfactoryaware.setbeanfactory (
Call Beanpostprocessor.postprocessbeforeinitialization (), color is empty, set to default black. Call Initializingbean.afterpropertiEsset () invokes the Myinit () specified by Inti-method and sets the maxspeed to 240.
Call Beanpostprocessor.postprocessafterinitialization () and adjust the Maxspedd to 200.
Chery QQ