Bean的BeanLifeCycle
在Java中Bean 的生命周期一般是:1.定义;2.初始化;3.使用;4.销毁
在Spring中Bean的生命周期:
从图中,我们可以看到实例化Bean的过程中有以下几个节点:
1)设置属性值;
2)调用Bean中的BeanNameAware.setBeanName()方法,如果该Bean实现了BeanNameAware接口;
3)调用Bean中的BeanFactoryAware.setBeanFactory()方法,如果该Bean实现了BeanFactoryAware接口;
4)调用BeanPostProcessors.postProcessBeforeInitialization()方法;
5)调用Bean中的afterPropertiesSet方法,如果该Bean实现了InitializingBean接口;
6)调用Bean中的init-method,通常是在配置bean的时候指定了init-method,例如:<bean class="beanClass" init-method="init"></bean>
7)调用BeanPostProcessors.postProcessAfterInitialization()方法;
8)如果该Bean是单例的,则当容器销毁并且该Bean实现了DisposableBean接口的时候,调用destory方法;如果该Bean是prototype,则将准备好的Bean提交给调用者,后续不再管理该Bean的生命周期。
Bean的初始化与销毁:
在Java当中,累的初始化是在构造函数当中,那么在Spring中,类怎么进行初始化呢?
1.构造函数:
2.自定义的初始化的方法:
自定义中有三种方法指定我们自定义的初始化、销毁的方法。
1.在<bean></bean>中指明属性:init-method、destroy-method的值并在相对应的bean中实现相对应的方法;
2.在<beans></beans>中指明属性:default-init-method、default-destroy-method的值并在相对应的bean中实现相对应的方法;
3.在bean中实现相对应的接口:org.springframework.beans.factory.InitializingBean,org.springframework.beans.factory.DisposableBean并实现相对应的方法。
几种方法的比较:
在相对应的bean中实现接口InitializingBean,DisposableBean并实现相对应afterPropertiesSet(),destroy()方法。在bean被初始化时候会自动的调用这些方法进行相对应的初始化。
在<bean></bean>中指明属性:init-method、destroy-method的值并在相对应的bean中实现相对应的方法。在当bean欲被初始化时候,会自动的调用这些方法进行想对应的方法进行初始化操作。
在<beans></beans>中指明属性default-init-method、default-destroy-method的值并在相对应的bean中实现相对应的方法。此方法是给该标签内的所有bean都给予声明构默认的初始化方法。在指明了这些属性的<beans></beans>标签中,<bean>中的属性init-method、destroy-method没有被重新制定且相对应的bean中也没有实现InitializingBean,DisposableBean这接口,就会调用默认的初始化、销毁的方法进行相对应的初始化与销毁。倘若在每一个<bean></bean>中都以重新指定了init-method、destroy-method属性或者相对应的bean以实现接口InitializingBean,DisposableBean,<beans></beans>中指明属性default-init-method、default-destroy-method相对应的方法就不会起到任何作用了,即使是没有实现这些方法也没有任何的影响。
问题来了,当构造方法与自定义的三种方法同时存在时候,他们的先后顺序是怎么一个样的呢?
实例说话:
Spring配置文件Xxx.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans default-init-method="defaultInit" default-destroy-method="defauleDestroy"> <bean id="bc" class="com.usc.geowind.lilin.bean.life.BCGame" init-method="init" destroy-method="stop" /> <bean id="cp" class="com.usc.geowind.lilin.bean.life.CPGame" init-method="init" destroy-method="stop" /> <bean id="play" class="com.usc.geowind.lilin.bean.life.Paly"> <property name="iGame" ref="cp"></property> </bean> </beans>
bean类:
public class CPGame implements IGame, InitializingBean, DisposableBean { public CPGame() { System.out.println("init CPGame by CPGame()!"); } public void init() { System.out.println("init CPGame by init()"); } public void stop() { System.out.println("CPGame stop"); } @Override public void play() { System.out.println("paly CP !"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("init CPGame by afterPropertiesSet() "); } @Override public void destroy() throws Exception { System.out.println("CPGame destroy"); } public void defaultInit() { System.out.println("init BCGame by defaultInit()"); } public void defauleDestroy() { System.out.println("BCGame defauleDestroy()"); } }
实例运行的现货顺序:
从打印的顺序可以看出来:构造方法还是首当其冲的,再到实现接口的方法,bean标签中自定义的初始化方法。然而,在<beans>标签中的默认初始化与销毁的方法没有起到任何的作用,是因为在<bena>中重新自定义了初始化的标签或者实现了初始化的接口。