Turn from: also on the life cycle of spring bean
Begin by using an old diagram to describe the life cycle of the bean container in spring.
Socialize, remember that a blog post mentions: "The Spring bean container only manages the life cycle of non-singleton beans, and the life cycle of the singleton Bean is not in the management range", in fact I think this sentence is right to say the opposite. First, it is clear that not all beans in the spring container have life-cycle behavior, only the bean that accepts the container management lifecycle has life-cycle behavior: While the singleton (Singleton) bean accepts container management, A non-singleton (Non-singleton) bean is fully assigned to client-side code management after it is instantiated, the container no longer tracks its lifecycle, and each time a customer requests that the container creates a new instance, so it is easy for spring to know when the bean is destroyed.
Keep on talking about the life cycle of the--bean container. In fact, there is a node that is not drawn, that is, Beanfactorypostprocessors is executed before all beans are instantiated. But also not care, because this and the bean's life cycle is not much related, so no mention is normal, right vote ignore the node.
, we can see the following nodes in the process of instantiating a bean:
1) Set the property value;
2) Call the Beannameaware.setbeanname () method in the bean, if the bean implements the Beannameaware interface;
3) Call the Beanfactoryaware.setbeanfactory () method in the bean, if the bean implements the Beanfactoryaware interface;
4) Call the Beanpostprocessors.postprocessbeforeinitialization () method;
5) Call the Afterpropertiesset method in the bean, if the bean implements the Initializingbean interface;
6) Invoke the Init-method in the bean, usually specifying the init-method when configuring the Bean, for example:<bean class= "Beanclass" init-method= "Init" ></ Bean>
7) Call the Beanpostprocessors.postprocessafterinitialization () method;
8) If the Bean is a singleton, the Destory method is called when the container is destroyed and the bean implements the Disposablebean interface, and if the bean is prototype, the prepared Bean is submitted to the caller, The life cycle of the bean is no longer managed by follow-up.
Well, it's a simple description of the next picture. Everything is too abstract, as a programmer, the code is the most straightforward way to express. Let's look at the demo code together.
First, to achieve the demo, we prepare two beans to be tested, with the following code:
@Component Public classDemobeanImplementsBeanfactoryaware, Beannameaware, Initializingbean, Disposablebean {@PostConstruct Public voidinit () {System.out.println ("Demobean:init-method"); } Public voidDestroy ()throwsException {System.out.println ("Demobean:destroy-method!"); } Public voidAfterpropertiesset ()throwsException {System.out.println ("Demobean:after Properties Set!"); } Public voidsetbeanname (String name) {System.out.println ("Demobean:beanname aware, [name=" + name + "]"); } Public voidSetbeanfactory (Beanfactory beanfactory)throwsbeansexception {System.out.println ("Demobean:beanfactory aware, [beanfactory=" + beanfactory.tostring () + "]"); } }
Public classAnotherdemobeanImplementsInitializingbean {@PostConstruct Public voidpostconstruct () {System.out.println ("Anotherdemobean:postconstruct-method"); } Public voidinit () {System.out.println ("Anotherdemobean:init-method"); } @Override Public voidAfterpropertiesset ()throwsException {System.out.println ("Anotherdemobean:after Properties Set!"); } }
The above two beans are roughly the same, the difference is that the first bean is injected using annotations, the second bean we use the configuration file, and specify its init-method, to observe the Init-method and postconstruct execution successively.
Our demo Bean implements Beanfactoryaware, Beannameaware, Initializingbean, Disposablebean these interfaces, in fact, these interfaces can also be understood as a spring container extension points.
We then write a beanpostprocessor that demonstrates steps 4 and 7 in the life cycle. The code is as follows:
@Component Public classDemobeanpostprocessorImplementsBeanpostprocessor { PublicObject Postprocessbeforeinitialization (Object bean, String beanname)throwsbeansexception {System.out.println ("Demobeanpostprocessor:post process before initialization, [beanname=" + Beanname + ", bean=" + Bean + "]"); returnBean; } PublicObject Postprocessafterinitialization (Object bean, String beanname)throwsbeansexception {System.out.println ("Demobeanpostprocessor:post process before initialization, [beanname=" + Beanname + ", bean=" + Bean + "]"); returnBean; } }
Finally, we write the test class, and the spring configuration file, where we use Classpathxmlapplicationcontext to load the configuration file and initialize the spring container. Look at the configuration file and test class code together:
Applicationcontext.xml:
<?xml version= "1.0" encoding= "GBK"?> <beans xmlns= "Http://www.springframework.org/schema/beans"Xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:aop= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP"Xmlns:context= "Http://www.springframework.org/schema/context" xmlns:tx= "Http://www.springframework.org/schema/tx"xsi:schemalocation= "http://Www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp//WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOPhttp://www.springframework.org/schema/aop/spring-aop-2.5.xsdhttp//Www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-2.5.xsdhttp//Www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsd"><context:component-scan base- Package= "Com.shansun.multidemo" ></context:component-scan> <beanclass= "Com.shansun.multidemo.spring.lifecycle.AnotherDemoBean" init-method= "Init" ></bean> </beans>
Main.java
Public class Main { @SuppressWarnings ("unused") publicstaticvoid Main (string[] args) { new classpathxmlapplicationcontext ("Applicationcontext.xml"); } }
All right, we're ready to go. Program output:
Demobean:beanname aware, [name=Demobean] Demobean:beanfactory aware, [Beanfactory=org.s[email protected]888e6c:defining Beans [Demobean,demobeanfactorypostprocessor,demobeanpostprocessor, Org.springframework.context.annotation.internalCommonAnnotationProcessor, Org.springframework.context.annotation.internalAutowiredAnnotationProcessor, Org.springframework.context.annotation.internalRequiredAnnotationProcessor, Com.shansun.multidemo.spring.lifecycle.anotherdemobean#0]; Root of factory hierarchy] Demobean:init-method Demobeanpostprocessor:post process before initialization, [Beanname=demobean, bean=[email protected]] Demobean:after Properties Set!Demobeanpostprocessor:post process before initialization, [Beanname=demobean, bean=[email protected]] Anotherdemobean:postconstruct-method Demobeanpostprocessor:post process before initialization, [Beanname=com.shansun.multidemo.spring.lifecycle.anotherdemobean#0, bean=[email protected]] Anotherdemobean:after Properties Set!Anotherdemobean:init-method Demobeanpostprocessor:post process before initialization, [Beanname=com.shansun.multidemo.spring.lifecycle.anotherdemobean#0, [email PROTECTED]DCF]
Is it the same as we expected? Yes. The observation found an interesting place: the Init-method specified in the configuration file and the method of using @postconstruct annotations, which are the first and the same? I will follow through the analysis of the source to give a conclusion .
We also validated the life cycle of the bean container by demonstrating the code, but what is the downside? By the way, is it more intuitive and convincing to tell the Bean container's life cycle through the spring source? Below we go to spring source of a probe. Here we choose the SPRING-2.5.6.SEC02.
Everyone should know the relationship between Beanfactory and ApplicationContext in spring, ApplicationContext inherits from Beanfactory, so it can be manipulated into beans. More detailed content can refer to Xilingpo's "Spring Framework design concept and Design pattern analysis", there is a clearer analysis.
Well, gossip doesn't say much.
First of all, we visited the method of instantiating the bean Initializebean, This method under the Org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory class, look at the code together:
protectedObject Initializebean (String beanname, Object bean, Rootbeandefinition mbd) {if(Beaninstanceofbeannameaware) {(beannameaware) bean). Setbeanname (Beanname); } if(Beaninstanceofbeanclassloaderaware) {(beanclassloaderaware) bean). Setbeanclassloader (Getbeanclassloader ()); } if(Beaninstanceofbeanfactoryaware) {(beanfactoryaware) bean). Setbeanfactory ( This); } Object Wrappedbean=Bean; if(mbd = =NULL|| !mbd.issynthetic ()) {Wrappedbean=applybeanpostprocessorsbeforeinitialization (Wrappedbean, beanname); } Try{invokeinitmethods (Beanname, Wrappedbean, mbd); } Catch(Throwable ex) {Throw Newbeancreationexception ((mbd!=NULL? Mbd.getresourcedescription ():NULL), Beanname,"Invocation of Init method failed", ex); } if(mbd = =NULL|| !mbd.issynthetic ()) {Wrappedbean=applybeanpostprocessorsafterinitialization (Wrappedbean, beanname); } returnWrappedbean; }
That's intuitive, isn't it the same as it was described earlier, J?
This article source code download: https://lb-multi-demo.googlecode.com/svn/trunk/spring-lifecycle-test
by Mr.chris
Spring Bean life cycle