Spring其實(shí)就是一個(gè)管理Bean對(duì)象的工廠。它負(fù)責(zé)對(duì)象的創(chuàng)建,對(duì)象的銷毀等。
所謂的生命周期就是:對(duì)象從創(chuàng)建開(kāi)始到最終銷毀的整個(gè)過(guò)程。
什么時(shí)候創(chuàng)建Bean對(duì)象?
創(chuàng)建Bean對(duì)象的前后會(huì)調(diào)用什么方法?
Bean對(duì)象什么時(shí)候銷毀?
Bean對(duì)象的銷毀前后調(diào)用什么方法?
1 Bean的生命周期之5步
Bean
生命周期的管理,可以參考Spring
的源碼:AbstractAutowireCapableBeanFactory類的doCreateBean()方法
。
Bean
生命周期可以粗略的劃分為五大步:
- 第一步:實(shí)例化
Bean
- 第二步:
Bean
屬性賦值 - 第三步:初始化
Bean
(會(huì)調(diào)用Bean
的init
方法。注意:這個(gè)init
方法需耍自已寫,自己配。) - 第四步:使用
Bean
- 第五步:銷毀
Bean
(會(huì)調(diào)用Bean
的destroy
方法。注意:這個(gè)destroy
方法需耍自已寫,自己配。)
public class User {
private String name;
public User() {
System.out.println("第一步:無(wú)參數(shù)構(gòu)造方法執(zhí)行");
}
public void setName(String name) {
System.out.println("第二步:給對(duì)象的屬性賦值");
this.name = name;
}
//需要自己寫,自己配
public void initBean() {
System.out.println("第三步:初始化Bean");
}
//需要自己寫,自己配
public void destroy() {
System.out.println("第五步:銷毀Bean");
}
}
init-method="initBean" destroy-method="destroy"
<bean id="user" class="com.cjf.bean.User" init-method="initBean" destroy-method="destroy">
<property name="name" value="zs"/>
</bean>
@Test
public void testBeanLifeCycleFive() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("springBean.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println("第四步:使用Bean: " + user);
//注意:必須手動(dòng)關(guān)閉Spring容器,才會(huì)銷毀Bean
ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) applicationContext;
context.close();
}
2 Bean生命周期之7步
在以上的5步中,第3步是初始化Bean
,如果你還想在初始化前和初始化后添加代碼,可以加入“Bean后處理器”。
編寫一個(gè)類實(shí)現(xiàn)BeanPostProcessor
類,并且重寫before
和after
方法:
-
第一步:實(shí)例化Bean
-
第二步:Bean屬性賦值
-
第三步:執(zhí)行“Bean后處理器”的
before
方法 -
第四步:初始化Bean(會(huì)調(diào)用Bean 的init方法。注意:這個(gè)
init
方法需耍自已寫,自己配。) -
第五步:執(zhí)行“Bean后處理器”的
after
方法 -
第六步:使用Bean
-
第七步:銷毀Bean(會(huì)調(diào)用Bean的destroy 方法。注意:這個(gè)
destroy
方法需耍自已寫,自己配。)
測(cè)試類
@Test
public void testBeanLifeCycleFive() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("springBean.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println("第六步:使用Bean: " + user);
//注意:必須手動(dòng)關(guān)閉Spring容器,才會(huì)銷毀Bean
ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) applicationContext;
context.close();
}
LogBeanPostProcessor
public class LogBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("執(zhí)行Bean后處理器的before方法");
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("執(zhí)行Bean后處理器的after方法");
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
SpringBean.xml
<!--配置Bean后處理器-->
<!--注意:這個(gè)Bean后處理器將作用于整個(gè)配置文件所有的bean-->
<bean class="com.cjf.bean.LogBeanPostProcessor"/>
<bean id="user" class="com.cjf.bean.User" init-method="initBean" destroy-method="destroy">
<property name="name" value="zs"/>
</bean>
源碼分析
3 Bean生命周期之10步
點(diǎn)位:
-
在“Bean后處理器”before方法之
前
- 檢查Bean是否實(shí)現(xiàn)類
Aware
相關(guān)的接口,若實(shí)現(xiàn)了則調(diào)用這些接口中的方法 - 然后調(diào)用這些方法的目的是為了給你傳遞一些數(shù)據(jù),讓你更加方便使用。
- 檢查Bean是否實(shí)現(xiàn)類
-
在“Bean后處理器”before方法之
后
- 檢查Bean是否實(shí)現(xiàn)
InitializingBean
- 檢查Bean是否實(shí)現(xiàn)
-
使用Bean之后,或者在
銷毀
Bean之前 -
- 檢查Bean是否實(shí)現(xiàn)
DisposableBean
- 檢查Bean是否實(shí)現(xiàn)
-
添加的這三個(gè)點(diǎn)位的特點(diǎn)。都是在檢查你這個(gè)
Bean
是否實(shí)現(xiàn)了某些特定的接口,如果實(shí)現(xiàn)了這些接口,則Spring
容器會(huì)調(diào)用這個(gè)接口中的方法。
如果根據(jù)源碼跟蹤,可以劃分更細(xì)粒度的步驟,10步:
是否實(shí)現(xiàn)了Aware
的相關(guān)接口是什么意思?
Aware
相關(guān)的接口包括:BeanNameAware
、BeanClassLoaderAware
、BeanFactoryAware
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-464761.html
- 當(dāng)Bean實(shí)現(xiàn)了
BeanNameAware
,Spring會(huì)將Bean的名字
傳遞給Bean。 - 當(dāng)Bean實(shí)現(xiàn)了
BeanClassLoaderAware
,Spring會(huì)將加載該Bean的類加載器
傳遞給Bean。 - 當(dāng)Bean實(shí)現(xiàn)了
BeanFactoryAware
,Spring會(huì)將Bean工廠對(duì)象
傳遞給Bean。
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-464761.html
public class User implements InitializingBean,DisposableBean, BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {
private String name;
public User() {
System.out.println("第一步:無(wú)參數(shù)構(gòu)造方法執(zhí)行");
}
public void setName(String name) {
System.out.println("第二步:給對(duì)象的屬性賦值");
this.name = name;
}
//需要自己寫,自己配
public void initBean() {
System.out.println("第四步:初始化Bean");
}
//需要自己寫,自己配
public void myDestroy() {
System.out.println("第七步:銷毀Bean");
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("Bean這個(gè)類的加載器: " + classLoader);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("生產(chǎn)Bean的工廠是: " + beanFactory);
}
@Override
public void setBeanName(String s) {
System.out.println("Bean的名字: " + s);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean 的 afterPropertiesSet 方法執(zhí)行");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean 的 destroy 方法執(zhí)行");
}
}
到了這里,關(guān)于7、Bean的生命周期的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!