解析配置類
解析配置類流程圖:https://www.processon.com/view/link/5f9512d5e401fd06fda0b2dd
解析配置類思維腦圖:https://www.processon.com/view/link/614c83cae0b34d7b342f6d14
- 在啓動Spring時,需要傳入一個AppConfig.class給ApplicationContext,ApplicationContext會根據AppConfig類封裝爲一個BeanDefinition,這種BeanDefinition我們把它稱爲配置類BeanDefinition。
- ConfigurationClassPostProcessor中會把配置類BeanDefinition取出來
- 構造一個ConfigurationClassParser用來解析配置類BeanDefinition,並且會生成一個配置類對象ConfigurationClass
- 如果配置類上存在@Component註解,那麼解析配置類中的內部類(這裏有遞歸,如果內部類也是配置類的話)
- 如果配置類上存在@PropertySource註解,那麼則解析該註解,並得到PropertySource對象,並添加到environment中去
- 如果配置類上存在@ComponentScan註解,那麼則解析該註解,進行掃描,掃描得到一系列的BeanDefinition對象,然後判斷這些BeanDefinition是不是也是配置類BeanDefinition(只要存在@Component註解就是配置類,所以基本上掃描出來的都是配置類),如果是則繼續解析該配置類,(也有遞歸),並且會生成對應的ConfigurationClass
- 如果配置類上存在@Import註解,那麼則判斷Import的類的類型:
- 如果是ImportSelector,那麼調用執行selectImports方法得到類名,然後在把這個類當做配置類進行解析(也是遞歸)
- 如果是ImportBeanDefinitionRegistrar,那麼則生成一個ImportBeanDefinitionRegistrar實例對象,並添加到配置類對象中(ConfigurationClass)的importBeanDefinitionRegistrars屬性中。
- 如果配置類上存在@ImportResource註解,那麼則把導入進來的資源路徑存在配置類對象中的importedResources屬性中。
- 如果配置類中存在@Bean的方法,那麼則把這些方法封裝爲BeanMethod對象,並添加到配置類對象中的beanMethods屬性中。
- 如果配置類實現了某些接口,則看這些接口內是否定義了@Bean的默認方法
- 如果配置類有父類,則把父類當做配置類進行解析
- AppConfig這個配置類會對應一個ConfigurationClass,同時在解析的過程中也會生成另外的一些ConfigurationClass,接下來就利用reader來進一步解析ConfigurationClass
- 如果ConfigurationClass是通過@Import註解導入進來的,則把這個類生成一個BeanDefinition,同時解析這個類上@Scope,@Lazy等註解信息,並註冊BeanDefinition
- 如果ConfigurationClass中存在一些BeanMethod,也就是定義了一些@Bean,那麼則解析這些@Bean,並生成對應的BeanDefinition,並註冊
- 如果ConfigurationClass中導入了一些資源文件,比如xx.xml,那麼則解析這些xx.xml文件,得到並註冊BeanDefinition
- 如果ConfigurationClass中導入了一些ImportBeanDefinitionRegistrar,那麼則執行對應的registerBeanDefinitions進行BeanDefinition的註冊
總結一下
- 解析AppConfig類,生成對應的ConfigurationClass
- 再掃描,掃描到的類都會生成對應的BeanDefinition,並且同時這些類也是ConfigurationClass
- 再解析ConfigurationClass的其他信息,比如@ImportResource註解的處理,@Import註解的處理,@Bean註解的處理
本系列文章來自圖靈學院周瑜老師分享,本博客整理學習並搬運