Spring Bean 批量註冊

@Configration和@Bean註解詳解

  1. @Configuration註解修飾的類,會被spring通過cglib做增強處理,通過cglib會生成一個代理對象,代理會攔截所有被@Bean註解修飾的方法,可以確保一些bean是單例的

  2. 不管@Bean所在的類上是否有@Configuration註解,都可以將@Bean修飾的方法作爲一個bean註冊到spring容器中

@ComponentScan、@ComponentScans詳解

@ComponentScan用於批量註冊bean

  1. spring會按照這個註解的配置,遞歸掃描指定包中的所有類,將滿足條件的類批量註冊到spring容器中.
  2. 可以通過value、basePackages、basePackageClasses 這幾個參數來配置包的掃描範圍
  3. 可以通過useDefaultFilters、includeFilters、excludeFilters這幾個參數來配置類的過濾器,被過濾器處理之後剩下的類會被註冊到容器中
  4. @CompontScan註解會被ConfigurationClassPostProcessor類遞歸處理,最終得到所有需要註冊的類。

@ComponentScan工作的過程:

  1. Spring會掃描指定的包,且會遞歸下面子包,得到一批類的數組
  2. 然後這些類會經過上面的各種過濾器,最後剩下的類會被註冊到容器中

默認情況下,任何參數都不設置的情況下,此時,會將@ComponentScan修飾的類所在的包作爲掃描包;默認情況下useDefaultFilters爲true,這個爲true的時候,spring容器內部會使用默認過濾器,
規則是:凡是類上有@Repository、@Service、@Controller、@Component這幾個註解中的任何一個的,那麼這個類就會被作爲bean註冊到spring容器中,所以默認情況下,只需在類上加上這幾個註解中的任何一個,這些類就會自動交給spring容器來管理了。

@Import

作用就是和xml配置的 <import />標籤作用一樣,允許通過它引入@Configuration標註的類 , 引入ImportSelector接口和ImportBeanDefinitionRegistrar接口的實現,也包括 @Component註解的普通類

@Import註解是被下面這個類處理的
org.springframework.context.annotation.ConfigurationClassPostProcessor
@Configuration、@Bean、@CompontentScan、@CompontentScans都是被這個類處理的.

@Import的value常見的有5種用法

  1. value爲普通的類
  2. value爲@Configuration標註的類
  3. value爲@CompontentScan標註的類
  4. value爲ImportBeanDefinitionRegistrar接口類型
  5. value爲ImportSelector接口類型
  6. value爲DeferredImportSelector接口類型

value爲ImportBeanDefinitionRegistrar接口類型
這個接口提供了通過spring容器api的方式直接向容器中註冊bean。
主要參數

  • importingClassMetadata
    AnnotationMetadata類型的,通過這個可以獲取被@Import註解標註的類所有註解的信息。
  • registry
    BeanDefinitionRegistry類型,是一個接口,內部提供了註冊bean的各種方法。
    BeanDefinitionRegistry接口:bean定義註冊器
    AnnotationConfigApplicationContext類也實現了這個接口
    BeanDefinition接口:bean定義信息
    用來表示bean定義信息的接口,我們向容器中註冊bean之前,會通過xml或者其他方式定義bean的各種配置信息,bean的所有配置信息都會被轉換爲一個BeanDefinition對象,然後通過容器中BeanDefinitionRegistry接口中的方法,將BeanDefinition註冊到spring容器中,完成bean的註冊操作。

value爲ImportBeanDefinitionRegistrar接口類型
用法:

  1. 定義ImportBeanDefinitionRegistrar接口實現類,在registerBeanDefinitions方法中使用registry來註冊bean
  2. 使用@Import來導入步驟1中定義的類
  3. 使用步驟2中@Import標註的類作爲AnnotationConfigApplicationContext構造參數創建spring容器
  4. 使用AnnotationConfigApplicationContext操作bean

value爲ImportSelector接口類型
用法
5. 定義ImportSelector接口實現類,在selectImports返回需要導入的類的名稱數組
6. 使用@Import來導入步驟1中定義的類
7. 使用步驟2中@Import標註的類作爲AnnotationConfigApplicationContext構造參數創建spring容器
8. 使用AnnotationConfigApplicationContext操作bean

攔截bean實例的創建,返回代理對象,
BeanPostProcessor#postProcessAfterInitialization

DeferredImportSelector接口
springboot中的核心功能@EnableAutoConfiguration就是靠DeferredImportSelector來實現的。
DeferredImportSelector是ImportSelector的子接口,既然是ImportSelector的子接口,所以也可以通過@Import進行導入,這個接口和ImportSelector不同地方有兩點:

  1. 延遲導入
  2. 指定導入的類的處理順序

延遲導入
比如@Import的value包含了多個普通類、多個@Configuration標註的配置類、多個ImportSelector接口的實現類,多個ImportBeanDefinitionRegistrar接口的實現類,還有DeferredImportSelector接口實現類,此時spring處理這些被導入的類的時候,會將DeferredImportSelector類型的放在最後處理,會先處理其他被導入的類,其他類會按照value所在的前後順序進行處理

參考

@Configration和@Bean註解詳解(bean批量註冊)
@ComponentScan、@ComponentScans詳解(bean批量註冊)
@import詳解(bean批量註冊)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章