深刻理解@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等。

相关文章
相关标签/搜索