一、注解SpringBootApplication

  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Inherited
  5. @SpringBootConfiguration
  6. @EnableAutoConfiguration
  7. @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
  8. @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
  9. public @interface SpringBootApplication {
  10. /**
  11. * 为注解 EnableAutoConfiguration exclude 字段赋值
  12. */
  13. @AliasFor(annotation = EnableAutoConfiguration.class)
  14. Class<?>[] exclude() default {};
  15. /**
  16. * 为注解 EnableAutoConfiguration excludeName 字段赋值
  17. */
  18. @AliasFor(annotation = EnableAutoConfiguration.class)
  19. String[] excludeName() default {};
  20. /**
  21. * 为注解 ComponentScan scanBasePackages 字段赋值
  22. */
  23. @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
  24. String[] scanBasePackages() default {};
  25. /**
  26. * 为注解 ComponentScan scanBasePackageClasses 字段赋值
  27. */
  28. @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
  29. Class<?>[] scanBasePackageClasses() default {};
  30. /**
  31. * 为注解 ComponentScan nameGenerator字段赋值
  32. */
  33. @AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
  34. Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
  35. /**
  36. * 为注解 Configuration proxyBeanMethods 字段赋值
  37. */
  38. @AliasFor(annotation = Configuration.class)
  39. boolean proxyBeanMethods() default true;

是一个复合注解,聚合了@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan

  • SpringBootConfiguration:本质是Configuration注解(本质是@Component)
  • EnableAutoConfiguration:本质导入AutoConfigurationImportSelector(实现DeferredImportSelector)、AutoConfigurationPackages.Registrar(实现ImportBeanDefinitionRegistrar, DeterminableImports)
  • ComponentScan:本质是 Spring 提供的指定扫描路径的注解。

    @SpringBootConfiguration

    本质是Configuration注解(本质是@Component)

    1. @Target(ElementType.TYPE)
    2. @Retention(RetentionPolicy.RUNTIME)
    3. @Documented
    4. @Configuration
    5. @Indexed
    6. public @interface SpringBootConfiguration {
    7. @AliasFor(annotation = Configuration.class)
    8. boolean proxyBeanMethods() default true;
    9. }

    @EnableAutoConfiguration

    标识开启自动配置。如果不用此注解则自动配置失效
    导入
    AutoConfigurationImportSelector(实现DeferredImportSelector)
    AutoConfigurationPackages.Registrar(实现ImportBeanDefinitionRegistrar, DeterminableImports)。
    因为实现DeferredImportSelector;在Springboot启动后,

  1. Spring容器会在解析完自定义的配置类后。
  2. 再执行AutoConfigurationImportSelector#selectImports 逻辑(解析配置到(项目spring-boot-autoconfigure的)META-INFO目录下的文件,获取Spingboot提供的所有自动配置类)
  3. 结合条件注解,最终引入Springboot对应预制的配置类
  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Inherited
  5. @AutoConfigurationPackage
  6. @Import(AutoConfigurationImportSelector.class)
  7. public @interface EnableAutoConfiguration {
  8. /**
  9. * Environment property that can be used to override when auto-configuration is
  10. * enabled.
  11. */
  12. String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
  13. /**
  14. * Exclude specific auto-configuration classes such that they will never be applied.
  15. * @return the classes to exclude
  16. */
  17. Class<?>[] exclude() default {};
  18. /**
  19. * Exclude specific auto-configuration class names such that they will never be
  20. * applied.
  21. * @return the class names to exclude
  22. * @since 1.3.0
  23. */
  24. String[] excludeName() default {};
  25. }

获取自动配置类集合流程

  1. 读取文件(/META-INF/spring/文件),获取springboot配置的所有自动配置类(以及其他组件提供的自动配置类,例如mybatis),集合configurations
  2. 对配置类集合:configurations,去重
  3. 获取注解:EnableAutoConfiguration属性exclude,配置的自动配置类排除项集合:exclusions
  4. configurations集合中,移除配置的排除项exclusions
  5. 获取Springboot中,默认的自动配置类过滤器集合(AutoConfigurationImportFilter实现类)。FilteringSpringBootCondition、OnBeanCondition、OnClassCondition、OnWebApplicationCondition
  6. 利用自动配置类过滤器集合中过滤器,筛选configurations集合,得到最终的自动配置类
  7. 发布Spring事件 ```java @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Import(AutoConfigurationPackages.Registrar.class) public @interface AutoConfigurationPackage {

    /**

    • Base packages that should be registered with {@link AutoConfigurationPackages}.
    • Use {@link #basePackageClasses} for a type-safe alternative to String-based package
    • names.
    • @return the back package names
    • @since 2.3.0 */ String[] basePackages() default {};

      /**

    • Type-safe alternative to {@link #basePackages} for specifying the packages to be
    • registered with {@link AutoConfigurationPackages}.
    • Consider creating a special no-op marker class or interface in each package that
    • serves no purpose other than being referenced by this attribute.
    • @return the base package classes
    • @since 2.3.0 */ Class<?>[] basePackageClasses() default {};

} ```

自动配置包路径

一般使用注解@AutoConfigurationPackage。
AutoConfigurationPackages.Registra类作用:将扫描路径变成一个Spring Bean对象。
即向Spring容器注册一个BasePackageBeanDefinition,这个对象默认存储Springboot默认扫描路径(即主类所在包路径)。

BasePackageBeanDefinition对应的实例对象,可以解决其他组件(例如mybatis)扫描路径存储,在集成其他框架没有配置扫描组件路径时,通过这个实例获取扫描路径(当然这个对象的内容,需要集成组件提供)。

@ComponentScan

Spring提供扫描注解,默认路径:主类所在包路径
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
AutoConfigurationExcludeFilter作用:扫描到的配置类名字如果在自动配置类集合中(文件读取),则延迟到解析自动配置时,进行解析。