這節呢,我們來學習下spring bean的生命周期。這部分内容較多,我分成幾篇來講述。
Bean的生命周期流程圖
先貼出我自己畫的Bean的生命周期流程圖

Bean的生命周期流程圖
若容器注冊了以上各種接口,程式那麼将會按照以上的流程進行。下面将仔細講解各接口作用。
加載配置檔案
萬裡長征第一步。Spring需要加載配置檔案,就是我們經常說的applicationContext.xml
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
解析配置檔案
這一步是為了将配置檔案中的等标簽資訊解析成Spring内部的BeanDefinition對象。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement{......}
BeanDefinition繼承了AttributeAccessor和BeanMetadataElement接口。
- AttributeAccessor:這是一個屬性通路者,它提供了通路屬性的能力。
public interface AttributeAccessor {void setAttribute(String name, @Nullable Object value);Object getAttribute(String name);Object removeAttribute(String name);boolean hasAttribute(String name);String[] attributeNames();}
- BeanMetadataElement:隻有一個方法,用來擷取中繼資料元素的配置源對象:
public interface BeanMetadataElement {Object getSource();}
BeanDefinition接口是Spring對bean的抽象。我們可以看下它包含的方法。
BeanDefinition接口
BeanDefinition包含了Bean需要的所有資訊,這樣Spring就可以利用BeanDefinition生成Bean了。
BeanFactoryPostProcessor和BeanPostProcessor對比
此處我們把這2個接口放在一起介紹。這2個接口很相似,但是有一些差別:
BeanFactoryPostProcessor:可以對bean的定義資訊(BeanDefinition)進行處理。也就是說,Spring IoC容器允許BeanFactoryPostProcessor在容器實際 執行個體化bean之前讀取 BeanDefinition 資料,并且可以修改它。比如修改Property或者scope。我們可以配置多個BeanFactoryPostProcessor。你還能 通過設定order屬性來控制BeanFactoryPostProcessor的執行次序。 BeanPostProcessor:後置bean處理器後置bean處理器,應用在允許自定義 修改新的bean執行個體。此時,IOC已經幫我們生成了對應的Bean對象。我們可以配置多個BeanPostProcessor。你還能 通過設定order屬性來控制BeanPostProcessor的執行次序。
BeanFactoryPostProcessor 接口
現在比較流行注解的方式來配置spring,是以我們隻保留applicationContext.xml,不再用xml 注冊Bean。
- applicationContext.xml
- 實體類
package com.sxdx.entity;import org.springframework.stereotype.Component;//使用注解注入一個名為processor的[email protected] class Processor {private String name;private int age;public Processor() {}public Processor(String name, int age) {this.name = name;this.age = age;}//get [email protected] String toString() {return "Processor{" +"name='" + name + ''' +", age=" + age +'}';}}
- BeanFactoryPostProcessor實作類
@Componentpublic class BeanFactoryPostProcessorOne implements BeanFactoryPostProcessor ,Ordered{@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("BeanFactoryPostProcessorOne");BeanDefinition dog = beanFactory.getBeanDefinition("processor");//通過BeanDefinition修改bean定義資訊if (dog != null){MutablePropertyValues mv = dog.getPropertyValues();mv.add("name","拉布拉多").add("age",22);}}@Overridepublic int getOrder() {return 1;}}
@Componentpublic class BeanFactoryPostProcessorTwo implements BeanFactoryPostProcessor , Ordered {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("BeanFactoryPostProcessorTwo");}@Overridepublic int getOrder() {return 2;}}
BeanFactoryPostProcessorTwo存在的意義主要是驗證是否支援排序接口。我們實作了Ordered
- 測試類
public class Test1 {private ApplicationContext applicationContext;@Beforepublic void initXmlBeanFactory() {System.out.println("========測試方法開始=======");applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");}@Afterpublic void after() {System.out.println("========測試方法結束=======");}@Testpublic void test() throws Exception {Processor processor = applicationContext.getBean("processor",Processor.class);System.out.println(processor.toString());}}
- 列印結果:
========測試方法開始=======BeanFactoryPostProcessorOneBeanFactoryPostProcessorTwoProcessor{name='拉布拉多', age=22}========測試方法結束=======
注意:
- 不要在BeanFactoryPostProcessor實作類中使用beanFactory.getBean()。此時尚未執行個體化。
- BeanFactoryPostProcessorOne在BeanFactoryPostProcessorTwo前執行,說明了BeanFactoryPostProcessor支援排序接口,且數字越小越先執行。
BeanPostProcessor 接口
我們在上面代碼的基礎上做修改。
- BeanPostProcessor實作類
@Componentpublic class BeanPostProcessorOne implements BeanPostProcessor , Ordered {public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("BeanPostProcessorOne");//擷取Bean執行個體,并修改if (beanName.equals("processor")){((Processor)bean).setAge(100);}return bean;}public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}@Overridepublic int getOrder() {return 2;}}
@Componentpublic class BeanPostProcessorTwo implements BeanPostProcessor , Ordered {public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("BeanPostProcessorTwo");return bean;}public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}@Overridepublic int getOrder() {return 1;}}
- 測試類
@Testpublic void test() throws Exception {Processor processor = applicationContext.getBean("processor",Processor.class);System.out.println(processor.toString());}
- 測試結果
========測試方法開始=======BeanFactoryPostProcessorOneBeanFactoryPostProcessorTwoBeanPostProcessorTwoBeanPostProcessorOneBeanPostProcessorTwoBeanPostProcessorOneBeanPostProcessorTwoBeanPostProcessorOneProcessor{name='拉布拉多', age=100}========測試方法結束=======
說明:
我們可以看到BeanFactoryPostProcessor先執行,驗證了BeanFactoryPostProcessor和BeanPostProcessor的生命周期執行順序。
BeanPostProcessorTwo在BeanPostProcessorOne前執行,說明了BeanPostProcessor 支援排序接口,且數字越小越先執行。
OK,Bean的生命周期(1)就先到這裡,下一篇繼續講流程圖中的其他内容。