深刻理解@SpringBootApplication

1 官方文檔

參見:18. Using the @SpringBootApplication Annotationjava

Many Spring Boot developers like their apps to use auto-configuration, component scan and be able to define extra configuration on their "application class". A single @SpringBootApplication annotation can be used to enable those three features, that is:app

  • @EnableAutoConfiguration: enable Spring Boot’s auto-configuration mechanism
  • @ComponentScan: enable @Component scan on the package where the application is located (see the best practices)
  • @Configuration: allow to register extra beans in the context or import additional configuration classes

The @SpringBootApplication annotation is equivalent to using @Configuration, @EnableAutoConfiguration, and @ComponentScan with their default attributes.源碼分析

2 翻譯

許多Spring Boot開發者們喜歡在ta們的應用程序中使用自動裝配,組件掃描,和可以在ta們的「應用程序類」上定義額外的配置。 單個@SpringBootApplication註釋可用於替代這三個功能,即ui

  • @EnableAutoConfiguration: 啓用Spring Boot的自動配置機制
  • @ComponentScan: 在應用程序所在的包上啓用@Component掃描(請參閱最佳實踐)
  • @Configuration: 容許在上下文中註冊額外的bean或導入其餘配置類

@SpringBootApplication註解等同於使用@Configuration@EnableAutoConfiguration@ComponentScan及其默認屬性。.net

3 源碼分析 version:2.0.2.RELEASE

3.1 SpringBootApplication註解分析

先看看@SpringBootApplication的源碼:翻譯

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
		@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {...}

接着看看@SpringBootConfiguration@Configuration的源碼:code

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration { }

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {...}

據此,能看出一點什麼嗎? 是的,@Configuration註解上標註了@Component@Configuration其實是@Component的"派生"註解。一樣的道理,@SpringBootApplication標註了@SpringBootConfigurationcomponent

因此,咱們獲得三者的關係:three

  • @Component
    • @Configuration
      • @SpringBootApplication

對的,上面三者具備層級關係。小馬哥的書中稱之爲多層次@Component'派生性',這種能力容許開發人員擴展使用。開發

再回到@SpringBootApplication,標註了@ComponentScan,代表能夠掃描到@Component,剛纔咱們已經分析了,@SpringBootConfiguration屬於多層次的@Component"派生"註解,屬於可以被@ComponentScan識別。

以此類推,@Repository@Service@Controller均屬於@Component"派生"註解,不過它們是直接"派生",官方稱之爲"Spring模式註解"。

3.2 SpringBootApplication屬性別名

首先看一個在項目中經常使用的屬性使用:

@SpringBootApplication(scanBasePackages = "com.xxx.yyy.zzz")
public class AppApplication {...}

前面咱們翻譯了官方的說明,@SpringBootApplication能夠等同於@EnableAutoConfiguration@ComponentScan,那麼原理是什麼呢?

咱們先介紹一個新的註解@AliasFor,一樣地,先看看官方文檔的介紹:

@AliasFor is an annotation that is used to declare aliases for annotation attributes.

翻譯過來:

@AliasFor是用於聲明註解屬性的別名註解。

個人理解就是,經過@AliasFor,一個註解能夠把另一個註解的屬性以別名的方式加到註解的屬性上面。下面咱們再看看@SpringBootApplication的屬性方法聲明:

@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 {};

看完這段源碼,是否是有種豁然開朗的感受,@SpringBootApplication能夠等同於@EnableAutoConfiguration@ComponentScan其實就是經過@AliasFor,把另外兩個註解的屬性經過別名的方式"聚合"到了本身的身上。相似的註解還有@RestController等。

相關文章
相關標籤/搜索