spring中Bean的生命週期總結
spring中在ApplicationContext或在BeanFactory中Bean的生命週期總結
Spring中Bean的生命週期,在學習spring的過程中bean的生命週期理解對學習spring有很大的幫助,下面我就分別介紹在ApplicationContext和BeanFactory中Bean的生命週期。
1、在ApplicationContext中Bean的生命週期
生命週期執行的過程如下:
1、需找所有的bean根據bean定義的資訊來例項化bean
2、使用依賴注入,spring按bean定義資訊配置bean的所有屬性
3、若bean實現了BeanNameAware介面,工廠呼叫Bean的setBeanName()方法傳遞bean的ID。
4、若bean實現了BeanFactoryAware介面,工廠呼叫setBeanFactory() 方法傳入工廠自身。
5、若bean實現了ApplicationContextAware()介面,setApplicationContext()方法會被呼叫
6、若BeanPostProcessor和bean關聯,
則它們的postProcessBeforeInitialization()方法被呼叫
7、若bean指定了init-method="init"方法、,它將被呼叫。
8、若有BeanPostProcessor和bean關聯,
則它們的postProcessAfterInitialization()方法被呼叫
注意:通過已上操作,此時的Bean就可以被應用的系統使用,並講保留在BeanFactory工廠中直到不再需要為止.但我們也可以通過9或者10進行銷燬
9、若bean實現了DisposableBean介面,distroy()方法被呼叫
10、如果指定了destroy-method="close"定製的銷燬方法,就呼叫這個方法
案例分析:
建立一個實體Bean程式碼如下:
[java] view plaincopyprint?- package www.csdn.spring.dao;
- 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;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.ApplicationContextAware;
- publicclass HelloDaoImpl implements BeanNameAware, BeanFactoryAware,
- InitializingBean, ApplicationContextAware, DisposableBean {
- private String content;
- public HelloDaoImpl() {
- System.out.println("----------HelloDaoImpl例項化");
- }
- publicvoid setContent(String content) {
- System.out.println("----------通過依賴注入的內容是:" + content);
- this.content = content;
- }
- @Override
- publicvoid setBeanName(String beanId) {
- System.out.println("----------輸出BeanId:" + beanId);
- }
- @Override
- publicvoid setBeanFactory(BeanFactory factory) throws BeansException {
- System.out.println("----------factory:" + factory.getClass());
- }
- @Override
- publicvoid setApplicationContext(ApplicationContext applicationContext)
- throws BeansException {
- System.out.println("----------" + applicationContext);
- }
- @Override
- publicvoid afterPropertiesSet() throws Exception {
- System.out.println("----------afterPropertiesSet");
- }
- publicvoid init() {
- System.out.println("----------初始化方法");
- }
- @Override
- publicvoid destroy() throws Exception {
- System.out.println("----------bean被銷燬");
- }
- publicvoid close() {
- System.out.println("----------close");
- }
- }
package www.csdn.spring.dao;
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;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class HelloDaoImpl implements BeanNameAware, BeanFactoryAware,
InitializingBean, ApplicationContextAware, DisposableBean {
private String content;
public HelloDaoImpl() {
System.out.println("----------HelloDaoImpl例項化");
}
public void setContent(String content) {
System.out.println("----------通過依賴注入的內容是:" + content);
this.content = content;
}
@Override
public void setBeanName(String beanId) {
System.out.println("----------輸出BeanId:" + beanId);
}
@Override
public void setBeanFactory(BeanFactory factory) throws BeansException {
System.out.println("----------factory:" + factory.getClass());
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
System.out.println("----------" + applicationContext);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("----------afterPropertiesSet");
}
public void init() {
System.out.println("----------初始化方法");
}
@Override
public void destroy() throws Exception {
System.out.println("----------bean被銷燬");
}
public void close() {
System.out.println("----------close");
}
}
建立BeanPostProcessor實現類
[java] view plaincopyprint?- package www.csdn.spring.dao;
- import org.springframework.beans.BeansException;
- import org.springframework.beans.factory.config.BeanPostProcessor;
- publicclass BeanPostProcessorImpl implements BeanPostProcessor {
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName)
- throws BeansException {
- System.out.println("我把:" + beanName + "例項化化之前的操作");
- return bean;
- }
- @Override
- public Object postProcessAfterInitialization(Object bean, String beanName)
- throws BeansException {
- System.out.println("我把:" + beanName + "例項化化之後的操作");
- return bean;
- }
- }
package www.csdn.spring.dao;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class BeanPostProcessorImpl implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("我把:" + beanName + "例項化化之前的操作");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("我把:" + beanName + "例項化化之後的操作");
return bean;
}
}
在配置檔案中配置實體Bean和BeanPostProcessorImpl特殊的Bean
[html] view plaincopyprint?- <?xmlversion="1.0"encoding="UTF-8"?>
- <beansxmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
- <!-- spring容器 就是負責建立、管理、維護Bean 並且能夠依賴注入到相應元件上 -->
- <beanid="helloDaoImpl"class="www.csdn.spring.dao.HelloDaoImpl"
- scope="singleton"lazy-init="false"init-method="init"destroy-method="close">
- <!-- 通過set方法注入 -->
- <propertyname="content"value="陳老師早上好!"/>
- </bean>
- <!-- BeanPostProcessor與當前的bean都進行關聯 -->
- <beanclass="www.csdn.spring.dao.BeanPostProcessorImpl"/>
- </beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- spring容器 就是負責建立、管理、維護Bean 並且能夠依賴注入到相應元件上 -->
<bean id="helloDaoImpl" class="www.csdn.spring.dao.HelloDaoImpl"
scope="singleton" lazy-init="false" init-method="init" destroy-method="close">
<!-- 通過set方法注入 -->
<property name="content" value="陳老師早上好!" />
</bean>
<!-- BeanPostProcessor與當前的bean都進行關聯 -->
<bean class="www.csdn.spring.dao.BeanPostProcessorImpl" />
</beans>
建立測試類BeanTest
[java] view plaincopyprint?- package www.csdn.spring.bean.cycle;
- import org.junit.Test;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.ConfigurableApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- publicclass BeanTest {
- @Test
- publicvoid test() {
- ApplicationContext context = new ClassPathXmlApplicationContext(
- "classpath:spring-dao.xml");
- // 強制造型
- ConfigurableApplicationContext cont = (ConfigurableApplicationContext) context;
- // 執行關閉 可以考到 destory-method的方法的執行
- cont.close();
- }
- }
package www.csdn.spring.bean.cycle;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanTest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext(
"classpath:spring-dao.xml");
// 強制造型
ConfigurableApplicationContext cont = (ConfigurableApplicationContext) context;
// 執行關閉 可以考到 destory-method的方法的執行
cont.close();
}
}
執行結果如下:
總結:在ApplicationContext中Bean的生命週期
2、在 BeanFactory中Bean的生命週期
在BeanFactory中Bean的生命週期與ApplicationContext中bean的生命週期唯一不同的是:若bean實現了ApplicationContextAware()介面,在ApplicationContext中bean的生命週期中setApplicationContext()方法會被呼叫,而在BeanFactory中Bean的生命週期此方法不會被呼叫。
案例採用上個案例:測試類中測試程式碼如下:
[java] view plaincopyprint?- // 建立資源物件
- ClassPathResource resource = new ClassPathResource("spring-dao.xml");
- // 採用BeanFactory初始化容器
- ConfigurableBeanFactory cbf = new XmlBeanFactory(resource);
- // bean後置處理器必須通過addBeanPostProcessor(new BeanPostProcessorImpl())手動新增
- cbf.addBeanPostProcessor(new BeanPostProcessorImpl());
- //在配置檔案中給BeanPostProcessorImpl的bean加上id="beanPostProcessorImpl" //cbf.addBeanPostProcessor(cbf.getBean("beanPostProcessorImpl", BeanPostProcessorImpl.class));
- // 獲取Bean物件
- cbf.getBean("helloDaoImpl", HelloDaoImpl.class);
- // 銷燬
- cbf.destroySingletons();
// 建立資源物件
ClassPathResource resource = new ClassPathResource("spring-dao.xml");
// 採用BeanFactory初始化容器
ConfigurableBeanFactory cbf = new XmlBeanFactory(resource);
// bean後置處理器必須通過addBeanPostProcessor(new BeanPostProcessorImpl())手動新增
cbf.addBeanPostProcessor(new BeanPostProcessorImpl());
//在配置檔案中給BeanPostProcessorImpl的bean加上id="beanPostProcessorImpl" //cbf.addBeanPostProcessor(cbf.getBean("beanPostProcessorImpl", BeanPostProcessorImpl.class));
// 獲取Bean物件
cbf.getBean("helloDaoImpl", HelloDaoImpl.class);
// 銷燬
cbf.destroySingletons();
執行結果:
總結:在BeanFactory中Bean的生命週期
另外說明:
應用上下文與bean工廠的另一個重要區別是關於單例bean如何被載入。
bean工廠延遲載入所有bean,直到getBean()方法被呼叫。
應用上下文會在啟動後預載入所有單例bean.這樣可確保應用不需要等待他們被建立。