Springboot的自动装配原理:
@SpringBootApplication
进入 AutoConfigurationImportSelector类中,会调用 selectImports(方法),用于选择需要自动配置的类,并返回它们的全限定类名数组
AnnotationMetadata 是被注解修饰的类或方法的元数据
这个selectImports主要获取被@Import注解修饰的类的元数据信息。该方法的主要作用是根据一些条件,选择需要导入的自动配置类。 具体来说,该方法的实现逻辑如下:
- 首先通过isEnabled方法判断当前是否需要执行自动配置导入操作。
- 如果需要执行自动配置导入操作,则通过AutoConfigurationMetadataLoader.loadMetadata方法加载自动配置元数据,并通过getAutoConfigurationEntry方法获取自动配置实体。
- 最后,通过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最终返回的自动配置条目封装类:
- configurations:自动配置类的全限定类名,也就是实现自动配置的类。
- exclusions:排除自动配置的类的全限定类名数组。
- matched:是否匹配自动配置条件的标志,如果为false,则表示不需要自动配置。
- metadataReader:自动配置类的元数据读取器,用于读取自动配置类的元数据信息。
- propertySourceNames:属性源的名称数组,用于获取自动配置类的属性值。
- resource:自动配置类的资源对象,用于定位自动配置类的位置。
最后一步:
这行代码的作用是获取自动配置类的全限定类名数组,并将其转换成字符串数组返回。
其中,autoConfigurationEntry表示上面第二步获取的自动配置条目,getConfigurations()方法是AutoConfigurationEntry类中的方法,用于获取自动配置类的全限定类名数组。
最后我们就拿到了所有需要自动配置类的全限定名。
在后续Springboot用到某个功能,会检查自动配置类是否存在,如果存在会通过全限定名进行加载。
总结:
Spring Boot是通过Spring框架的@EnableAutoConfiguration
注解和spring.factories
文件来实现自动检查和自动加载自动配置类的。 具体来说,当我们在应用程序中使用某个特定的功能时,Spring Boot会自动检查该功能所需的自动配置类是否存在。具体的检查过程如下:
- Spring Boot会扫描classpath下所有的
META-INF/spring.factories
文件,寻找其中所有实现了org.springframework.boot.autoconfigure.EnableAutoConfiguration
接口的自动配置类。 - Spring Boot会根据当前应用程序的类路径和配置文件,确定需要的自动配置类,并将其传递给
spring.factories
文件中所有自动配置类让他们自行检查是否满足条件(有一些是用了Conditional条件的)。 - 如果自动配置类中的
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可以根据当前应用程序的需求,自动加载所需的自动配置类,从而简化了应用程序的配置过程。