深入理解SpringBoot自动装配原理

498 阅读2分钟

这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

前言

一般Spring Boot应用的启动类都位于 src/main/java根路径下

image.png

其中 @SpringBootApplication开启组件扫描和自动配置,而 SpringApplication.run则负责启动引导应用程序。

注解@SpringBootApplication

@SpringBootApplication是一个复合 Annotation,它将三个有用的注解组合在一起:

image.png

2.1. @SpringBootConfiguration

@SpringBootConfiguration就是 @Configuration,它是Spring框架的注解,标明该类是一个 JavaConfig配置类。而 @ComponentScan启用组件扫描,前文已经详细讲解过,这里着重关注 @EnableAutoConfiguration

2.2. @EnableAutoConfiguration

@EnableAutoConfiguration注解表示开启Spring Boot自动配置功能,Spring Boot会根据应用的依赖、自定义的bean、classpath下有没有某个类 等等因素来猜测你需要的bean,然后注册到IOC容器中。

2.2.1 @EnableAutoConfiguration 定义

Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

   /**
    * Environment property that can be used to override when auto-configuration is
    * enabled.
    */
   String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

   /**
    * Exclude specific auto-configuration classes such that they will never be applied.
    * @return the classes to exclude
    */
   Class<?>[] exclude() default {};

   /**
    * Exclude specific auto-configuration class names such that they will never be
    * applied.
    * @return the class names to exclude
    * @since 1.3.0
    */
   String[] excludeName() default {};

}

@Import(EnableAutoConfigurationImportSelector.class) 是重点。

2.2.2 EnableAutoConfigurationImportSelector

@Import注解用于导入类,并将这个类作为一个bean的定义注册到容器中,这里它将把 EnableAutoConfigurationImportSelector作为bean注入到容器中,而这个类会将所有符合条件的@Configuration配置都加载到容器中

@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
   if (!isEnabled(annotationMetadata)) {
      return NO_IMPORTS;
   }
   AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
   return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

这个类会扫描所有的jar包,将所有符合条件的@Configuration配置类注入的容器中,何为符合条件,看看 META-INF/spring.factories的文件内容: 我们看下SPringBoot启动类里面的内容,org.springframework.boot.autoconfigure下的META-INF/spring.factories

image.png

比如我们前面介绍的flyway数据库配置管理工具。

org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\

EnableAutoConfigurationImportSelector#selectImports方法何时执行?

在容器启动过程中执行: AbstractApplicationContext#refresh()方法