决战圣地玛丽乔亚Day43

发布时间 2023-03-28 18:50:51作者: EmiXXXt

Springboot的自动装配原理:

@SpringBootApplication

 

 

进入 AutoConfigurationImportSelector类中,会调用 selectImports(方法),用于选择需要自动配置的类,并返回它们的全限定类名数组

AnnotationMetadata 是被注解修饰的类或方法的元数据

这个selectImports主要获取被@Import注解修饰的类的元数据信息。该方法的主要作用是根据一些条件,选择需要导入的自动配置类。 具体来说,该方法的实现逻辑如下:

  1. 首先通过isEnabled方法判断当前是否需要执行自动配置导入操作。
  2. 如果需要执行自动配置导入操作,则通过AutoConfigurationMetadataLoader.loadMetadata方法加载自动配置元数据,并通过getAutoConfigurationEntry方法获取自动配置实体。
  3. 最后,通过autoConfigurationEntry.getConfigurations方法获取需要导入的自动配置类,并转换为String数组返回。

第一步.首先看一下loadMetadata

AutoConfigurationMetadataLoader读取classpath下的所有文件的META-INF/spring-autoconfigure-metadata.properties文件,并将其中的元数据信息合成到一起加载到AutoConfigurationMetadata接口的实现类中。

在加载完成后,获得一个合并了各种自动配置元数据的AutoConfigurationMetadata就可以用于支持自动配置的各种功能,例如条件判断、自动配置类的加载等。   参数classLoder是类加载器,用于加载自动配置元数据信息。

 

第二步.

 

 

 这个方法用于返回自动配置类的全限定类名、条件匹配器、属性源。并把他们封装在AutoConfigurationImportSelector类的内部类AutoConfigrationEntry中

看源码:

 

 

 

这里使用SpringFactoriesLoader来加载JAR包下面的META-INF/spring.factories文件

例如:spring-boot-autoconfigure-2.1.14.RELEASE.jar

 下面的META-INF/spring.factories  很多东西。

 

 

 

 

 

 

 

 

 

 

 

        首先,该方法会从缓存中查找是否已经加载过该类加载器的spring.factories文件,如果已经加载过,则直接返回缓存中的结果。

   如果缓存中没有该类加载器的结果,则会使用指定的类加载器或系统类加载器(如果指定的类加载器为null)加载META-INF/spring.factories文件,获取该文件中所有自动配置类的类名和对应的自动配置类名列表

  对于每一个找到的spring.factories文件,该方法会使用PropertiesLoaderUtils.loadProperties()方法加载该文件中的所有属性,然后遍历每一个属性,将所有的属性值保存为一个列表返回。

      最后,该方法会将所有自动配置类名和自动配置类名列表保存到一个MultiValueMap对象中,并将该对象缓存在cache中,以便下次使用同一个类加载器时可以直接返回缓存中的结果。 综上所述,该方法实现了从META-INF/spring.factories文件中加载自动配置类的功能,并使用缓存提高了性能。

 

getAutoConfigrationEntry最终返回的自动配置条目封装类:

  1. configurations:自动配置类的全限定类名,也就是实现自动配置的类。
  2. exclusions:排除自动配置的类的全限定类名数组。
  3. matched:是否匹配自动配置条件的标志,如果为false,则表示不需要自动配置。
  4. metadataReader:自动配置类的元数据读取器,用于读取自动配置类的元数据信息。
  5. propertySourceNames:属性源的名称数组,用于获取自动配置类的属性值。
  6. resource:自动配置类的资源对象,用于定位自动配置类的位置。

最后一步:

 

 

 这行代码的作用是获取自动配置类的全限定类名数组,并将其转换成字符串数组返回。

其中,autoConfigurationEntry表示上面第二步获取的自动配置条目,getConfigurations()方法是AutoConfigurationEntry类中的方法,用于获取自动配置类的全限定类名数组。

最后我们就拿到了所有需要自动配置类的全限定名。

在后续Springboot用到某个功能,会检查自动配置类是否存在,如果存在会通过全限定名进行加载。

 

总结:

Spring Boot是通过Spring框架的@EnableAutoConfiguration注解和spring.factories文件来实现自动检查和自动加载自动配置类的。 具体来说,当我们在应用程序中使用某个特定的功能时,Spring Boot会自动检查该功能所需的自动配置类是否存在。具体的检查过程如下:

  1. Spring Boot会扫描classpath下所有的META-INF/spring.factories文件,寻找其中所有实现了org.springframework.boot.autoconfigure.EnableAutoConfiguration接口的自动配置类。
  2. Spring Boot会根据当前应用程序的类路径和配置文件,确定需要的自动配置类,并将其传递给spring.factories文件中所有自动配置类让他们自行检查是否满足条件(有一些是用了Conditional条件的)。
  3. 如果自动配置类中的ConditionalOnXXX注解所指定的条件成立,那么该自动配置类就会被Spring Boot自动加载。 具体的自动加载过程如下:

 

Spring Boot会将所有需要自动配置的类的相关信息封装为AnnotationMetadata传递给EnableAutoConfigurationImportSelector类的selectImports()方法。

selectImports()方法会根据需要自动配置的功能列表和spring.factories文件中的自动配置类,生成一个自动配置类的全限定名数组。

Spring Boot会将该全限定名数组传递给AnnotationConfigApplicationContext类的构造函数,以便在应用程序启动时自动加载这些自动配置类。

cause:

AnnotationConfigApplicationContext类的构造函数可以接受一个或多个Java配置类的全限定名作为参数,这些配置类会被用来自动化配置应用程序的各个部分。在应用程序启动时,AnnotationConfigApplicationContext会读取这些配置类,然后根据其中的Bean定义来创建Bean实例,并将它们注册到应用程序上下文中。如果这些配置类中定义了一些自动配置类,那么这些自动配置类也会被加载并应用到应用程序中去。

综上所述,Spring Boot是通过@EnableAutoConfiguration注解和spring.factories文件来实现自动检查和自动加载自动配置类的。通过这种方式,Spring Boot可以根据当前应用程序的需求,自动加载所需的自动配置类,从而简化了应用程序的配置过程。