@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
在知道 @AliasFor 的功能之後,現在回來看 @SpringBootApplication 內部屬性(雖然Api 文件上寫的是 Optional Element ,但筆者還是習慣將其稱之屬性方法的屬性) 就比較清楚。
屬性可以分成前4個和後2個來看,exclude、excludeName 等同於 @EnableAutoConfiguration 的 exclude, excludeName ,在 Spring 啟動之時排除指定配置類別,這裡將以下方的程式區塊為例。
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class
})
DataSourceAutoConfiguration.class 這一個類別會去查找 application.yml or application.properties 之中關於 Source 的相關設定,那為什麼好多多的自動註冊類擺著不用呢 ?
這是因為DataSourceAutoConfiguration.class 只支援單一數據源頭,如果你要採用多個數據源頭的話,你就必須排除DataSourceAutoConfiguration 這個自動配置類別。
exclude, excludeName 功能是一樣的,只是一個是給定類別檔,另一個是單純給定類別名字,如
DataSourceAutoConfiguration.class(類別) 和 DataSourceAutoConfiguration (類別名字)
scanBasePackages = “com.scheep” ,Spring Boot 會將 source 下方目錄路徑為 com.scheep 資料夾以及其下所有子目錄標有 @Component 標籤的 class 掃描成 Bean ; scanBasePackageClasses 則是以指定類別所在資料夾及其下的所有子目錄標有 @Component 的類別將會掃描成 Bean 。
nameGenerator的屬性,是指向 Annotation ComponentScan ,其同名 namdGenerator 。
注意看到下方所接範型 Class< ? extends BeanNameGenerator> 接受 BeanNameGenerator 的繼承或是實作類別,又其中 BeanNameGenerator 是一個介面,功能是從 Bean Definition 之中產生 Bean Name 的策略方法(原文: Strategy interface for generating bean names for bean definitions. ),那這是什麼意思呢 ?
下方三個箭頭所指之處,是Springframework 寫好的三個實作 BeanNameGenerator 的類別,而這些類別有詳細實作如何產生 Bean Name ,這就是上方所說的策略方法。
這邊就以 AnnotationBeanNameGenerator 這個策略方法做說明,其來自下方的 package org.springframework.context.annotation.AnnotationBeanNameGenerator ,
下方截圖取自 AnnotationNameGenerator Api ,參考連結在下方
AnnotationNameGenerator 會為那些標有 @Component 或是那些將 @Component 作為 meta-annotation 的 Annotaion 譬如說 @Repository (點開 @Repository 的 Source Code 可以看到 @Component 就放在 @interface Repository 類別上面) 的類別產生 Bean Name 。
若@Component 有提供 value 的話, AnnotationNameGenerator 就會將其作為 Bean Name,若沒有提供的話,就會以這個類別的 short name 作為 Bean Name,官方檔案中的 com.xyz.FooServiceImpl 這是類別的名字,而short Name 就是在建立類別給的名稱,就是指 com.xyz.FooServiceImpl 最後的字節, FooServiceImpl 。
剩下的 proxyBeanMethods 為指向 Annotation Configuration 的 同名屬性,
這一部分牽涉到代理將單獨抽出來介紹。
參考資料
SpringBootApplication 官方 Api
Annotation EnableAutoConfiguration Api
https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/EnableAutoConfiguration.html
AnnotationBeanNameGenerator 策略方法
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/AnnotationBeanNameGenerator.htm