天天看點

Spring IOC容器 -- ApplicationContext中Bean的生命周期

        Spring中有兩大重要概念,IOC和AOP。想要掌握并精通這兩項技術,就要掌握Spring中Bean的生命周期原理。

        ApplicationContext是面向應用的,ApplicationContext可以了解為Spring的IOC容器,下面講解ApplicationContext中Bean的生命周期:

Spring IOC容器 -- ApplicationContext中Bean的生命周期

1. Bean的執行個體化

  首先容器啟動後,會對scope為singleton且非懶加載的bean進行執行個體化。

  容器在内部實作的時候,采用“政策模式”來決定采用何種方式初始化bean執行個體。通常,可以通過反射或者CGLIB動态位元組碼生成來初始化相應的bean執行個體或者動态生成其子類。預設情況下,容器内部采用CglibSubclassingInstantiationStartegy。容器隻要根據相應bean定義的BeanDefinition取得執行個體化資訊,結合CglibSubclassingInstantiationStartegy以及不同的bean定義類型,就可以傳回執行個體化完成的對象執行個體。但不是直接傳回構造完成的對象執行個體,而是以BeanWrapper對構造完成的對象執行個體進行包裹,傳回相應的BeanWrapper執行個體。這個BeanWrapper的實作類BeanWrapperImpl是對某個bean進行包裹,然後對包裹後的bean進行操作,比如設定或擷取bean的相應屬性值。

2. 設定對象屬性

  BeanWrapper繼承了PropertyAccessor接口,可以以同一的方式對對象屬性進行通路,同時又繼承了PropertyEditorRegistry和TypeConverter接口,然後BeanWrapper就可以很友善地對bean注入屬性了。

3. 如果Bean實作了BeanNameAware接口,會回調該接口的setBeanName()方法,傳入該bean的id,此時該Bean就獲得了自己在配置檔案中的id。

4. 如果Bean實作了BeanFactoryAware接口,會回調該接口的setBeanFactory()方法,傳入該Bean的BeanFactory,這樣該Bean就獲得了自己所在的BeanFactory.

5. 如果Bean實作了ApplicationContextAware接口,會回調該接口的setApplicationContext()方法,傳入該Bean的ApplicationContext, 這樣該Bean就獲得了自己所在的ApplicationContext.

6. 如果有一個Bean實作了BeanPostProcessor接口,并将該接口配置到配置檔案中,則會調用該接口的postProcessBeforeInitialization()方法。

7.如果Bean實作了InitializingBean接口,則會回調該接口的afterPropertiesSet()方法。

8. 如果Bean配置了init-method方法,則會執行init-method配置的方法。

9. 如果有一個Bean實作了BeanPostProcessor接口,并将該接口配置到配置檔案中,則會調用該接口的postProcessAfterInitialization方法。

10.經過9之後,就可以正式使用該Bean了,對于scope為singleton的Bean, Spring IoC容器會緩存一份該Bean的執行個體,而對于scope為prototype的Bean, 每次被調用都回new一個對象,而且生命周期也交給調用方管理了,不再是Spring容器進行管理了。

11. 容器關閉後,如果Bean實作了DisposableBean接口,則會調用該接口的destroy()方法。

12. 如果Bean配置了destroy-method方法,則會執行destroy-method配置的方法,至此,整個Bean生命周期結束。

總結:整個生命周期要執行的方法可以分為三類:

(一)Bean自身的方法:執行個體化Bean對象、設定對象屬性、調用init-method方法、調用destory-method方法

(二)Bean級别接口的方法:BeanNameAware接口的setBeanName()方法、BeanFactoryAware接口的setBeanFactory()方法、ApplicationContextAware接口的setApplicationContext()方法、InitializingBean接口的afterPropertiesSet()方法

(三)容器級别接口的方法:BeanPostProcessor接口的postProcessBeforeInitialization()方法、BeanPostProcessor接口的postProcessAfterInitialization()方法

繼續閱讀