Spring源碼之後置處理器(BeanPostProcessor)

1.Spring refresh過程中執行的beanPostProcessor

名稱 執行的方法 作用
instantiationAwareBeanPostProcessor postPorcessorBeforeInstantiation 對目標對象的初始化過程中需要處理的事情
smartInstantiationAwareBeanPostProcessor determineCandidateConstructors 推斷構造方法
mergedBeanDefinitionBeanPostProcessor postProcessorMergedBeanDefinition
smartInstantiationAwareBeanPostProcessor getEarlyBeanReference
instantiationAwareBeanPostProcessor postProcessorPropertyValues
smartBeanPostProcessor
BeanPostProcessor postProcessBeforeInitialization
BeanPostProcessor postProcessAfterInitialization

getBean獲取提前暴露出來的對象

beanDefinitionNames

1、核心beanPostProcessor

1.1.instantiationAwareBeanPostProcessor:

方法一: postProcessorBeforeInstantation:實例化之前執行,如果該方法返回了Object,後面只執行postProcessorAfterInitialization方法,其它方法不再調用。

方法二:postProcessorAfterInstantation:實例化之後調用。

方法三:postProcessorPropertyValues:設置對象屬性。

方法四:postProcessorBeforeInitialization:bean初始化之前執行,此時目標對象已經被實例化且屬性已經被設置。

方法五:postPorocessorAfterInitialization:bean初始化之前執行,此時目標對象已經被實例化且屬性已經被設置。

1.2.smartInstantiationAwareBeanPostProcessor

方法一:determineCandidateConstructors:檢測出bean的構造函數。

方法二:getEarlyBeanReference:解決循環引用問題的後置處理器,獲取提前暴露的引用。

1.3.mergedBeanDefinitionBeanPostProcessor

方法一:postProcessorMergedBeanDefinition:獲取bean的注入信息,並緩存起來

常見beanPostProcessor:

例子:

2、代碼跟蹤

2.1.mergedBeanDefinitionBeanPostProcessor

2.1.1.commonAnnocationAwareBeanPostProcessor
  1. 執行postProcessMergedBeanDefinition方法:在這裏插入圖片描述2. 第一步是執行父類InitDestroyAnnotationBeanPostProcessor的方法postProcessMergedBeanDefinition,從類名上也能很明顯看出,初始化和銷燬註解後置處理器。
    在這裏插入圖片描述

  2. 我們進入findLifecycleMetadata,先從緩存裏找,沒有找到,繼續往下走。重點是buildResourceMetadata方法,我們進入buildResourceMetadata看看。
    在這裏插入圖片描述

  3. 執行buildLifecycleMetadata方法,到此父類InitDestroyAnnotationBeanPostProcessor的方法postProcessMergedBeanDefinition已經執行完畢。
    在這裏插入圖片描述

  4. 第二步執行findResourceMetadata方法
    在這裏插入圖片描述
    先從緩存裏找,沒有找到,繼續往下走。重點是buildResourceMetadata方法,我們進入buildResourceMetadata看看。

  5. 執行buildResourceMetadata方法,下面我們看下關鍵的方法
    在這裏插入圖片描述
    到此核心的功能已經執行完畢。主要的作用就是找出@PostConstruct和@PreDestroy註解修飾的方法,放入到lifecycleMetadataCache緩存中;@Resource修飾的方法或者變量,放入到injectionMetadataCache緩存中。

2.1.2.autowiredAnnotationBeanPostProcessor
  1. 同樣,也是執行postProcessMergedBeanDefinition方法
    在這裏插入圖片描述
  2. 執行findAutowiringMetadata,先從緩存裏找,沒有找到,繼續往下走。重點是buildAutowiringMetadata方法,我們進入buildAutowiringMetadata看看。
    在這裏插入圖片描述
  3. 進入buildAutowiringMetadata方法,先利用反射,遍歷類所有的field,找出是否使用@Auwired 和@Value註解的field
    在這裏插入圖片描述
    再遍歷類所有的method,找出是否使用@Auwired 和@Value註解的method
    在這裏插入圖片描述
  4. 最後放入到injectionMetadataCache緩存中。到此核心的功能已經執行完畢。主要是找出@Value和@Autowired修飾的變量和方法,並放入到緩存中。

2.2.instantiationAwareBeanPostProcessor

2.2.1.commonAnnotationaBeanPostProcessor:
注入@Resource修飾的屬性的bean。
  1. 執行postProcessPropertyValues方法。
    在這裏插入圖片描述
    這裏我們又看到了findResourceMetadata方法,這次直接就可以從commonAnnocationAwareBeanPostProcessor類的injectionMetadataCache緩存中拿出來InjectionMetadata屬性。再調用inject方法
2.2.2.autowiredAnnotationBeanPostProcessor:
找出@Value和@Autowired修飾的變量和方法

在這裏插入圖片描述
執行postProcessPropertyValues方法,進入findAutowiringMetadata方法,從方法名也能看出來,是找出被@Autowired修飾的屬性,得到InjectionMetadata屬性
在這裏插入圖片描述
3. 這裏同樣直接就可以從AutowiredAnnotationBeanPostProcessor類的injectionMetadataCache緩存中拿出來InjectionMetadata屬性。再調用inject方法。

2.3.smartInstantiationAwareBeanPostProcessor

三、beanPostProcessor

1.ApplicationContextAwareProcessor: 定義一個bean實現ApplicationContextAware接口可以使它獲取到applicationContext應用上下文。

Spring是如何解決循環依賴:

概念說明:

Spring容器:

singletonObejcts (conCurrentHashMap) ,裏面存放交給Spring管理的bean,bean已經完全初始化好。

singletonFactories (hashMap) ,存放用來獲取提前暴露bean引用的ObjectFactory對象。

earlySingletonObjects(hashMap),存放原始的bean對象,屬性還未填充。

A依賴B B依賴A

  1. 屬性B(getSingleton(A)),實例化A,注入屬性B,獲取屬性B(getSingleton(B))
  2. 實例化B,注入屬性A,獲取屬性A(getSingleton(A))
    在這裏插入圖片描述
    首先從singletonObjects,也就是Spring容器獲取,第一次getSingleton(A),singletonObjects返回空,且isSingletonCurrentlyInCreation(A)返回空,

Spring初始化方法和銷燬方法:

  1. @PostConstruct和@PreDestroy註解的方法
  2. 實現InitializingBean接口和DisposableBean接口
  3. @Bean 的屬性 initMethod和destroyMethod方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章