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代碼如下:
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"); } }
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實現類
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; } }
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
<?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>
<?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
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(); } }
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的生命周期此方法不會被調用。
案例采用上個案例 :測試類中測試代碼如下:
// 創建資源對象 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.這樣可確保應用不需要等待他們 被創建。