SpringBoot---自动配置原理

SpringBoot --- 自动配置的原理

      • 1、关于SpringBoot自动配置
      • 2、SpringBoot的自动配置的原理
        • a.@SpringBootConfiguration
        • b.@ComponentScan
        • c.@EnableAutoConfiguration
          • @AutoConfigurationPackage
          • @Import({AutoConfigurationImportSelector.class})

1、关于SpringBoot自动配置

     SpringBoot的自动配置就是当spring容器启动后,一些自动配置类(只是自动配置类,并不是当前组件配置到IOC容器当中,自动配置类通过@Conditional注解来按需配置)就自动装配的IOC容器中,不需要我们手动去注入,从而简化了开发,省去了繁琐的配置。

2、SpringBoot的自动配置的原理

     一个SpringBoot工程想要成功运行,就必须拥有一个主程序类(被@SpringBootApplication 注解标识),而自动配置的相关工作就在 @SpringBootApplication这个注解上。
SpringBoot---自动配置原理
     当我们进去到 @SpringBootApplication 注解的源码当中,可以发现它是一个复合注解,它是由 @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan 这三个注解组成

SpringBoot---自动配置原理

a.@SpringBootConfiguration

     在@SpringBootConfiguration 源码中可以发现有 @Configuration,代表是一个配置类,说明主程序类也是一个配置类

b.@ComponentScan

指定扫描哪些组件,默认是扫描主程序所在的包以及其子包。

c.@EnableAutoConfiguration

@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
}
@AutoConfigurationPackage

将指定的一个包下的所有组件导入到容器当中
自动配置包
     在@AutoConfigurationPackage 注解中存在一个 @Import({Registrar.class}) 注解,自动配置包就是通过这个 Registrar 类的方法来完成的。

@Import({Registrar.class})  //给容器中导入一个组件
public @interface AutoConfigurationPackage {
    
//通过 Registrar 给容器中导入一系列组件
//将指定的一个包下的所有组件导入进来,MainApplication 所在的包下

SpringBoot---自动配置原理

     由于@AutoConfigurationPackage 是在 @EnableAutoConfiguration 中,所以@AutoConfigurationPackage 是标识在主程序类上,所以 metadata为主程序类

     在Registrar中的 registerBeanDefinitions 方法,首先先获取到注解所标识的类,然后将这个类所在的包以及子包的名称放入到一个String数组当中,再将该String数组中的包的所有组件导入到容器当中

public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
   AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));
 }

SpringBoot---自动配置原理
这也是为什么Spring容器启动后会自动导入 主程序所在的包及其子包中的所有组件

@Import({AutoConfigurationImportSelector.class})

该注解的大概流程就是:将 spring-boot-autoconfigure-x.x.x.jar包中 META-INF/spring.factories文件中的

    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }
getAutoConfigurationEntry(annotationMetadata); //给容器批量导入一些组件

     selectImports()是AutoConfigurationImportSelector的核心函数,其核心功能就是获取spring.factories中EnableAutoConfiguration所对应的Configuration类列表,由@EnableAutoConfiguration注解中的exclude/excludeName参数筛选一遍,再由AutoConfigurationImportFilter类所有实例筛选一遍,得到最终的用于Import的configuration和exclusion。
SpringBoot---自动配置原理

SpringBoot---自动配置原理

List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);//获取到所有需要导入到容器当中的组件
利用工厂加载 Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) //得到所有组件
从META-INF/spring.factories 位置来加载一个文件
    默认扫描我们当前系统里面所有 META-INF/spring.factories位置的文件
    spring-boot-autoconfigure-2.6.7.jar包里边也有  META-INF/spring.factories

SpringBoot---自动配置原理

configurations中一共有 133个组件,

SpringBoot---自动配置原理

SpringBoot---自动配置原理

SpringBoot---自动配置原理

可以发现,spring-boot-autoconfigure-2.6.7.jar包里边也有 META-INF/spring.factories, 而 spring.factories 的 EnableAutoConfiguration,正好有133条,而configurations中正好也有 133 条,所以configurations中读取到的内容,正好是 spring.factories 的 EnableAutoConfiguration 中的内容

文件里面写死了 SpringBoot 一启动就要给容器中加载的所有自动配置类

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
.........

最后按需开启自动配置项

虽然133个场景的所有自动配置启动的时候默认全部加载但是,按照条件装配规则,最终会按需配置,需要使用到 @Conditional 注解以及其子注解 ,按需加载

版权声明:程序员胖胖胖虎阿 发表于 2022年8月30日 下午10:48。
转载请注明:SpringBoot---自动配置原理 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...