1. 程式人生 > >spring中Bean的生命週期總結

spring中Bean的生命週期總結

spring中在ApplicationContext或在BeanFactory中Bean的生命週期總結

 Spring中Bean的生命週期,在學習spring的過程中bean的生命週期理解對學習spring有很大的幫助,下面我就分別介紹在ApplicationContextBeanFactoryBean的生命週期。

1、在ApplicationContextBean的生命週期

生命週期執行的過程如下:

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?
  1. package www.csdn.spring.dao;  
  2. import org.springframework.beans.BeansException;  
  3. import org.springframework.beans.factory.BeanFactory;  
  4. import org.springframework.beans.factory.BeanFactoryAware;  
  5. import org.springframework.beans.factory.BeanNameAware;  
  6. import org.springframework.beans.factory.DisposableBean;  
  7. import org.springframework.beans.factory.InitializingBean;  
  8. import org.springframework.context.ApplicationContext;  
  9. import org.springframework.context.ApplicationContextAware;  
  10. publicclass HelloDaoImpl implements BeanNameAware, BeanFactoryAware,  
  11. InitializingBean, ApplicationContextAware, DisposableBean {  
  12. private String content;  
  13. public HelloDaoImpl() {  
  14. System.out.println("----------HelloDaoImpl例項化");  
  15. }  
  16. publicvoid setContent(String content) {  
  17. System.out.println("----------通過依賴注入的內容是:" + content);  
  18. this.content = content;  
  19. }  
  20. @Override
  21. publicvoid setBeanName(String beanId) {  
  22. System.out.println("----------輸出BeanId:" + beanId);  
  23. }  
  24. @Override
  25. publicvoid setBeanFactory(BeanFactory factory) throws BeansException {  
  26. System.out.println("----------factory:" + factory.getClass());  
  27. }  
  28. @Override
  29. publicvoid setApplicationContext(ApplicationContext applicationContext)  
  30. throws BeansException {  
  31. System.out.println("----------" + applicationContext);  
  32. }  
  33. @Override
  34. publicvoid afterPropertiesSet() throws Exception {  
  35. System.out.println("----------afterPropertiesSet");  
  36. }  
  37. publicvoid init() {  
  38. System.out.println("----------初始化方法");  
  39. }  
  40. @Override
  41. publicvoid destroy() throws Exception {  
  42. System.out.println("----------bean被銷燬");  
  43. }  
  44. publicvoid close() {  
  45. System.out.println("----------close");  
  46. }  
  47. }  
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?
  1. package www.csdn.spring.dao;  
  2. import org.springframework.beans.BeansException;  
  3. import org.springframework.beans.factory.config.BeanPostProcessor;  
  4. publicclass BeanPostProcessorImpl implements BeanPostProcessor {  
  5. @Override
  6. public Object postProcessBeforeInitialization(Object bean, String beanName)  
  7. throws BeansException {  
  8. System.out.println("我把:" + beanName + "例項化化之前的操作");  
  9. return bean;  
  10. }  
  11. @Override
  12. public Object postProcessAfterInitialization(Object bean, String beanName)  
  13. throws BeansException {  
  14. System.out.println("我把:" + beanName + "例項化化之後的操作");  
  15. return bean;  
  16. }  
  17. }  
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;

}


}

在配置檔案中配置實體BeanBeanPostProcessorImpl特殊的Bean

[html] view plaincopyprint?
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <beansxmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.            http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <!-- spring容器 就是負責建立、管理、維護Bean 並且能夠依賴注入到相應元件上 -->
  7. <beanid="helloDaoImpl"class="www.csdn.spring.dao.HelloDaoImpl"
  8. scope="singleton"lazy-init="false"init-method="init"destroy-method="close">
  9. <!-- 通過set方法注入 -->
  10. <propertyname="content"value="陳老師早上好!"/>
  11. </bean>
  12. <!-- BeanPostProcessor與當前的bean都進行關聯 -->
  13. <beanclass="www.csdn.spring.dao.BeanPostProcessorImpl"/>
  14. </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?
  1. package www.csdn.spring.bean.cycle;  
  2. import org.junit.Test;  
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.ConfigurableApplicationContext;  
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  6. publicclass BeanTest {  
  7. @Test
  8. publicvoid test() {  
  9. ApplicationContext context = new ClassPathXmlApplicationContext(  
  10. "classpath:spring-dao.xml");  
  11. // 強制造型
  12. ConfigurableApplicationContext cont = (ConfigurableApplicationContext) context;  
  13. // 執行關閉 可以考到 destory-method的方法的執行
  14. cont.close();  
  15. }  
  16. }  
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();


}

}

執行結果如下:

總結:在ApplicationContextBean的生命週期

2、在 BeanFactoryBean的生命週期

     在BeanFactoryBean的生命週期與ApplicationContextbean的生命週期唯一不同的是:若bean實現了ApplicationContextAware()介面,在ApplicationContextbean的生命週期中setApplicationContext()方法會被呼叫,而在BeanFactoryBean的生命週期此方法不會被呼叫。

案例採用上個案例:測試類中測試程式碼如下:

[java] view plaincopyprint?
  1. // 建立資源物件
  2. ClassPathResource resource = new ClassPathResource("spring-dao.xml");  
  3. // 採用BeanFactory初始化容器
  4. ConfigurableBeanFactory cbf = new XmlBeanFactory(resource);  
  5. // bean後置處理器必須通過addBeanPostProcessor(new BeanPostProcessorImpl())手動新增
  6. cbf.addBeanPostProcessor(new BeanPostProcessorImpl());  
  7. //在配置檔案中給BeanPostProcessorImpl的bean加上id="beanPostProcessorImpl" //cbf.addBeanPostProcessor(cbf.getBean("beanPostProcessorImpl", BeanPostProcessorImpl.class));
  8. // 獲取Bean物件
  9. cbf.getBean("helloDaoImpl", HelloDaoImpl.class);  
  10. // 銷燬
  11. 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();

執行結果:

總結:在BeanFactoryBean的生命週期

另外說明:

     應用上下文與bean工廠的另一個重要區別是關於單例bean如何被載入。

bean工廠延遲載入所有bean,直到getBean()方法被呼叫。

應用上下文會在啟動後預載入所有單例bean.這樣可確保應用不需要等待他們被建立。