[SpringBoot] Spring Boot的核心注解是哪个

Spring Boot的核心注解是哪个?它由哪几个注解组成?

1.1 @SpringBootApplication

Spring Boot的核心注解是@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 {
...
}

关于该注解,源码是这么解释的:

Indicates a configuration class that declares one or more @Bean methods and also triggers auto-configuration and component scanning. This is a convenience annotation that is equivalent to declaring @Configuration, @EnableAutoConfiguration and @ComponentScan.
 
来源:spring-boot-autoconfigure:2.1.2.RELEASE

译文:

表明这是一个配置类,里面声明了一个或多个@Bean方法。同时也触发了自动配置和组件扫描。使用该注解也可以带来便利,因为它等价于同时声明了@Configuration, @EnableAutoConfiguration 和 @ComponentScan 三个注解

从源代码和文档可知,其主要由3个注解组成:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

那么,这3个注解都有哪些作用呢

注:如果你使用的是idea,可以通过快捷键Ctrl+Q,打开方法或类的说明文档

1.2 @SpringBootConfiguration

注解@SpringBootConfiguration的源码如下:

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

}

有两点需要说明:

  1. 该注解没有属性
  2. 其继承于Spring的标准注解@Configuration

打开@SpringBootConfiguration的说明文档:

Indicates that a class provides Spring Boot application @Configuration. Can be used as an alternative to the Spring’s standard @Configuration annotation so that configuration can be found automatically (for example in tests).
Application should only ever include one @SpringBootConfiguration and most idiomatic Spring Boot applications will inherit it from @SpringBootApplication.
 
来源:spring-boot:2.1.2.RELEASE

译文如下:

表明某个类提供 Spring Boot 应用的配置。可用于替代Spring的标准注解@Configuration,以便于能够自动找到配置(例如在测试代码中)。
 
应用应当只包含一个 @SpringBootConfiguration注解。并且大多数地道的 Spring Boot 应用都会从 @SpringBootApplication继承它(言下之意,不会直接使用该注解,而是通过@SpringBootApplication间接地使用该注解

结合前面的信息,我们可知:

  • 标注@SpringBootConfiguration的类是一个配置类,所以启动类本质上也是一个配置类
  • 在 Spring Boot 应用中,通过@SpringBootApplication 间接地使用 @SpringBootConfiguration 类。

1.3 @EnableAutoConfiguration

@EnableAutoConfiguration的文档说明如下:

Enable auto-configuration of the Spring Application Context, attempting to guess and configure beans that you are likely to need. Auto-configuration classes are usually applied based on your classpath and what beans you have defined. For example, if you have tomcat-embedded.jar on your classpath you are likely to want a TomcatServletWebServerFactory (unless you have defined your own ServletWebServerFactory bean).
 
When using SpringBootApplication, the auto-configuration of the context is automatically enabled and adding this annotation has therefore no additional effect.
 
Auto-configuration tries to be as intelligent as possible and will back-away as you define more of your own configuration. You can always manually exclude() any configuration that you never want to apply (use excludeName() if you don’t have access to them). You can also exclude them via the spring.autoconfigure.exclude property. Auto-configuration is always applied after user-defined beans have been registered.
 
The package of the class that is annotated with @EnableAutoConfiguration, usually via @SpringBootApplication, has specific significance and is often used as a ‘default’. For example, it will be used when scanning for @Entity classes. It is generally recommended that you place @EnableAutoConfiguration (if you’re not using @SpringBootApplication) in a root package so that all sub-packages and classes can be searched.
 
Auto-configuration classes are regular Spring Configuration beans. They are located using the SpringFactoriesLoader mechanism (keyed against this class). Generally auto-configuration beans are @Conditional beans (most often using @ConditionalOnClass and @ConditionalOnMissingBean annotations).
 
来源:spring-boot-autoconfigure:2.1.2.RELEASE

译文:

当启用Spring应用程序上下文的自动配置后,框架会尝试猜测和配置您可能需要的bean。
自动配置的类通常会根据classpath和你已经定义的bean而决定是否生效。比如,如果你的classpath中有tomcat-embedded.jar组件,那么Spring猜测你可能需要一个类型为TomcatServletWebServerFactory 的bean(除非你已经自定义ServletWebServerFactory的bean)。
 
当使用SpringBootApplication时,上下文的自动配置是自动启用的,因此添加该注解没有额外的作用。
 
自动配置会试图尽可能的智能化,会随着你自定义配置的增加而进行回退。你总是能够手动排除那些你压根不需要的配置(使用exclude() 方法),如果你没有访问权限,则可以通过excludeName()方法进行排除。你也可以通过spring.autoconfigure.exclude属性排除它们。自动配置总是在用户定义bean注册之后才会生效。
 
用@EnableAutoConfiguration注释的类所在的包,具有特定的意义。通常被作为默认的扫描路径。例如,在扫描@Entity类时,通常建议 将标有@EnableAutoConfiguration注解的类放置到根目录 中,以便于能够扫描到所有的子包和类。
 
自动配置类是常规的Spring配置bean。它们使用 SpringFactoriesLoader 机制 进行定位。通常自动配置bean也是 @Conditional 标注的bean(通常使用 @ConditionalOnClass 和 @ConditionalOnMissingBean进行标注)。

那么什么是SpringFactoriesLoader机制呢?
看官方解释:

General purpose factory loading mechanism for internal use within the framework.
SpringFactoriesLoader loads and instantiates factories of a given type from “META-INF/spring.factories” files which may be present in multiple JAR files in the classpath. The spring.factories file must be in Properties format, where the key is the fully qualified name of the interface or abstract class, and the value is a comma-separated list of implementation class names. For example:
example.MyService=example.MyServiceImpl1,example.MyServiceImpl2
where example.MyService is the name of the interface, and MyServiceImpl1 and MyServiceImpl2 are two implementations.
 
来源:spring-core:5.1.4.RELEASE

译文:

spring框架内部使用的 通用工厂加载机制 。SpringFactoriesLoader 从"META-INF/spring.factories"文件中读取工厂类型,并加载和实例化这些工厂类型。
 
spring.factories文件可能存在于classpath中的多个JAR文件。spring.factories文件必须使用Properties 文件格式,即key必须是 接口或是抽象类的完全限定名 ,同时value是用逗号分隔的实现类名称的列表
例子:

example.MyService=example.MyServiceImpl1,example.MyServiceImpl2

其中,example.MyService是接口的名称,而example.MyServiceImpl1和example.MyServiceImpl2是两个实现类。

从上面的描述,我们知道了SpringFactoriesLoader机制是如何工作的:它依赖于spring.factories文件,并根据该文件加载工厂实现类

1.4 @ComponentScan

源码如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
...
}

相关的文档说明如下:

Configures component scanning directives for use with @Configuration classes. Provides support parallel with Spring XML’s <context:component-scan> element.
Either basePackageClasses or basePackages (or its alias value) may be specified to define specific packages to scan. If specific packages are not defined, scanning will occur from the package of the class that declares this annotation.
 
Note that the <context:component-scan> element has an annotation-config attribute; however, this annotation does not. This is because in almost all cases when using @ComponentScan, default annotation config processing (e.g. processing @Autowired and friends) is assumed. Furthermore, when using AnnotationConfigApplicationContext, annotation config processors are always registered, meaning that any attempt to disable them at the @ComponentScan level would be ignored.
 
来源:spring-context:5.1.4.RELEASE

译文:

配置与@Configuratioin类一起使用的组件扫描指令。提供与Spring XML的<context:component-scan>元素并行的支持(功能一致)。
 
可以指定 basepackageclass 或 basePackages (或者其别名value)来定义要扫描的指定包。如果指定包没有定义,将从标记该注解的类所在的包开始扫描。
 
需要指出的是<context:component-scan>元素有一个annotation-config属性,然而@ComponentScan注解却没有此属性。这是因为

1.5 总结

  @SpringBootApplication 注解是Spring Boot的核心注解。它本质上组合了3个注解:@SpringBootConfiguration,@EnableAutoConfiguration 和 @ComponentScan
  通常将@SpringBootApplication注解打到Spring Boot应用的启动类上。并且启动类一般位于应用的根目录,这样做可以确保扫描到所有的子包和类。
  还顺带提到了什么是 SpringFactoriesLoader机制。该机制依赖于spring.factories文件,并根据该文件加载工厂实现类。
  @ComponentScan注解如果没有指定要扫描的路径,将从标记该注解的类所在的包开始扫描。而@SpringBootApplication 上也标记了@ComponentScan注解,并且没有显式指定扫描路径,所以该规则也同样适用于@SpringBootApplication 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值