搜索Bean生命週期有很多博客,大部分是Copy,有些還是錯的。
最近我看了源碼,仔細瞭解了下流程,先上圖:
獲取Bean
這個時候InstantiationAwareBeanPostProcessor有機會通過postProcessBeforeInstantiation方法(執行後執行applyBeanPostProcessorsAfterInitialization方法)直接返回一個Bean對象,不走下面的流程。
- Bean 實例化(構造方法)
- 將實例的引用放入第三級緩存singletonFactories中
- Bean屬性配置
- 所有的InstantiationAwareBeanPostProcessor執行postProcessAfterInstantiation
- 所有的 InstantiationAwareBeanPostProcessor執行postProcessProperties,postProcessPropertyValues
- AutowiredAnnotationBeanPostProcessor 這裏會去找Bean的@AutoWired和@Refrence的Bean(比如A依賴了B)並且去加載
- 如果此依賴Bean(比如B)反過來依賴了原Bean(比如A)。首先去singletonObjects中尋找A,沒有找到。那麼會從第三級緩存singletonFactories將A取出來,放入earlySingletonObjects中.並且B依賴此引用A.等待B加載完成,A再依賴B
- AutowiredAnnotationBeanPostProcessor 這裏會去找到@Value註解的值,裝配上
- AutowiredAnnotationBeanPostProcessor 這裏會去找Bean的@AutoWired和@Refrence的Bean(比如A依賴了B)並且去加載
- Bean 初始
- 實現了BeanNameAware 執行setBeanName
- 實現了BeanClassLoaderAware執行setBeanClassLoader
- 實現了BeanFactoryAware 執行setBeanFactory
- 調用所有的BeanPostProcessor的postProcessorBeforeInitialization
- 實現了ApplicationContextAware執行setApplicationContext,這個邏輯寫在ApplicationContextAwareProcessor中,其實也是一個BeanPostProcessor,與setBeanName等不同
- 實現了InitializingBean執行afterPropertiesSet
- 執行配置的init-method
- 調用所有的BeanPostProcessor的postProcessorAfterInitialization
- 加入singletonObjects,並且從earlySingletonObjects,singletonFactories中去除自身引用
- Bean銷燬
InstantiationAwareBeanPostProcessor 繼承了 BeanPostProcessor,在Bean實例化的時候起作用。由於也是BeanPostProcessor,理論上在Bean初始化的時候也能起作用。
三級緩存,均爲HashMap:首先從singletonObjects取,其次從earlySingletonObjects中取,取不到再去singletonFactories中取。從singletonFactories取之後放入earlySingletonObjects中。
spring藉此機制完成了Bean循環依賴的解決。但是如果是通過構造方法的循環依賴,AB的構造方法中均依賴了對方,那麼循環依賴不能解決。