SpringBoot启动类上的注解

SpringBoot启动类上的注解

2019.09.07


在看完我的上一篇文章创建一个SpringBoot工程后,有很多人也许会疑问springboot的启动类上的这个**@SpringBootApplication**到底起着什么样的作用,本文将就这个疑问做详细的记录。简单来说,本文的主要内容涉及以下两点:

1、@SpringBootApplication注解含义与源码
2、启动类的位置将定义包扫描位置


@SpringBootApplication注解含义与源码

首先给出通过IDEA创建的一个简单SpringBoot工程目录结构

  • 工程结构

SpringBoot启动类上的注解_第1张图片
通过这个结构,我们不难发现,SpringBoot将我们项目的启动类放在了classpath:/com/rain/abdemo01/下,而在这个路径及其子路径下,我们在后续的开发中还会接连定义些其他的需要注入到springboot容器中的组件,那么想必springboot帮我们这样做是事出有因还是无中生有,我们再来看一下在启动类上的注解及其源码:

  • Sbdemo01Application.java
@SpringBootApplication
public class Sbdemo01Application {
    public static void main(String[] args) {
        SpringApplication.run(Sbdemo01Application.class, args);
    }
}
  • SpringBootApplication.java
@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 {
    @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 {};
}
  • SpringBootConfiguration.java
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}

从源码中我们不难发现,@SpringBootConfiguration是对@SpringBootApplication的定义,而在@SpringBootConfiguration的注解定义中还用到了@Configuration作为注解的描述,因此可做以下归纳:

  1. @SpringBootApplication实质上是对@SpringBootConfiguration(即@Configuration)与@EnableAutoConfiguration以及@ComponentScan的组合注解。
  2. @SpringBootConfiguration(即@Configuration)表示被注解的启动类为SpringBoot应用的一个主配置类。
  3. @EnavleAutoConfiguration表示在这个主配置类上开启SpringBoot的自动配置。
  4. @ComponentScan则定义了SpringBoot容器的组件扫描规则。

因此@SpringBootApplication具有以上的4个主要功能。

启动类的位置将定义包扫描位置

上文已提到,springboot将启动类放在了classpath:/com/rain/sbdemo01/下,springboot这么做的原因再结合对SpringBootApplication注解定义中的ComponentScan注解,我们便可知道,启动类的位置定义了springboot容器的包扫描位置,即启动类所在包及其子包。这更加凸显了springboot的"约定大于配置"的先进理念。
但是如果一定要修改启动类的位置,为了使程序中的其他所有组件被springboot容器扫描到,在技术上也可做如下配置,但是仅供参考,并不推荐。

  • 工程目录
    SpringBoot启动类上的注解_第2张图片

  • Sbdemo01Application.java

@SpringBootApplication
@ComponentScan(basePackages = "com.rain.sbdemo01")
public class Sbdemo01Application {
    public static void main(String[] args) {
        SpringApplication.run(Sbdemo01Application.class, args);
    }
}

如上图所示,由于将启动类放置在了classpath:/com/rain/sbdemo01/config/下,因此如果不重新定义包扫描规则,则springboot默认只会扫描classpath:/com/rain/sbdemo01/config/下的路径,所以需要用@ComponentScan来重新定义包扫描规则。


看到这里,如果小伙伴们有什么更好的想法欢迎在下面的讨论区一起讨论!
这个专栏也会陆续更新我的springboot学习记录,愿与君共勉!

你可能感兴趣的:(springboot,springboot,spring,springmvc)