随着SpringBoot的大规模使用,我们有必要来了解一下SpringBoot底层是如何为我们进行一系列配置的
这是一个SpringBoot的启动类,运行该类就能启动我们的SpringBoot服务
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
我们查看一下这个启动类上的@SpringBootApplication这个注解,这个注解实际上是一个复合注解,我们点进去可以看到这个注解还包含了其他的几个注解,@SpringBootConfiguration、@EnabLeAutoConfiguration、@componentscan
@SpringBootConfiguration和@componentscan
@SpringBootConfiguration注解就是一个@Configuration,代表当前是一个配置类,而@componentscan的含义是指定扫描那些位置,自动配置的关键在于第三个注解@EnabLeAutoConfiguration (开启自动配置)
@EnabLeAutoConfiguration
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
这个注解也是一个复合注解,里面包含了@AutoConfigurationPackage(自动配置包),同时这个自动配置包的注解里面又包含一个@Import(AutoConfigurationPackages.Registrar.class),这个注解的意思是给容器中导入一个Registrar组件
@AutoConfigurationPackage
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)//给容器中导入一个组件
public @interface AutoConfigurationPackage {
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
}
Registrar
Registrar中有两个方法,参数为AnnotationMetadata,这个参数中记录了当前注解标注的类的信息,包括类的位置,包路径之类的信息,利用Registrar给容器中批量的添加组件,添加的范围是@EnabLeAutoConfiguration这个注解标注的类的所在包,也就是我们springBoot的启动类所在的包,这样就解释了为什么我们经常说启动类包下的所有资源都会加载之类的
@Import(AutoConfigurationImportSelector.class)
接下来说说@EnabLeAutoConfiguration的最后一个注解,用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件,调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类,利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件,从META-INF/spring.factories位置来加载一个文件。默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件, spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories
总结
SpringBoot的自动配置关键的注解是@EnabLeAutoConfiguration,这个注解里面包含了包扫描规则以及spring-boot-autoconfigure-2.3.4.RELEASE.jar包中有META-INF/spring.factories路径下配置写死的需要配置的文件信息,虽然里面的所有都会被加载,但是实际上还是遵循的按需加载原则,因为里面很多xxxxAutoConfiguration是需要我们导入了相关的依赖才能成功加载的。