4.3.5 SpringFactoriesLoader.loadFactoryNames 方法@Import(AutoConfigurationImportSelector.class) 表示直接注入AutoConfigurationImportSelector 。
AutoConfigurationImportSelector 有一个核心方法getCandidateConfigurations 用于获取候选配置 。该方法调用了SpringFactoriesLoader.loadFactoryNames 方法,这个方法即为 Spring Boot SPI 的关键,它负责加载所有 META-INF/spring.factories 文件,加载的过程由 SpringFactoriesLoader 负责 。
Spring Boot 的 META-INF/spring.factories 文件本质上就是一个 properties 文件,数据内容就是一个个键值对 。
SpringFactoriesLoader.loadFactoryNames 方法的关键源码:
// spring.factories 文件的格式为:key=value1,value2,value3// 遍历所有 META-INF/spring.factories 文件// 解析文件,获得 key=factoryClass 的类名称public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {String factoryTypeName = factoryType.getName();return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());}private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {// 尝试获取缓存,如果缓存中有数据,直接返回MultiValueMap<String, String> result = cache.get(classLoader);if (result != null) {return result;}try {// 获取资源文件路径Enumeration<URL> urls = (classLoader != null ?classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));result = new LinkedMultiValueMap<>();// 遍历所有路径while (urls.hasMoreElements()) {URL url = urls.nextElement();UrlResource resource = new UrlResource(url);// 解析文件,得到对应的一组 PropertiesProperties properties = PropertiesLoaderUtils.loadProperties(resource);// 遍历解析出的 properties,组装数据for (Map.Entry<?, ?> entry : properties.entrySet()) {String factoryTypeName = ((String) entry.getKey()).trim();for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {result.add(factoryTypeName, factoryImplementationName.trim());}}}cache.put(classLoader, result);return result;}catch (IOException ex) {throw new IllegalArgumentException("Unable to load factories from location [" +FACTORIES_RESOURCE_LOCATION + "]", ex);}}归纳上面的方法,主要作了这些事:
加载所有 META-INF/spring.factories 文件,加载过程有 SpringFactoriesLoader 负责 。
- 在 CLASSPATH 中搜寻所有 META-INF/spring.factories 配置文件 。
- 然后,解析 spring.factories 文件,获取指定自动装配类的全限定名 。
以 spring-boot-starter-web 的 jar 包为例,查看其 maven pom,可以看到,它依赖于 spring-boot-starter,所有 Spring Boot 官方 starter 包都会依赖于这个 jar 包 。而 spring-boot-starter 又依赖于 spring-boot-autoconfigure,Spring Boot 的自动装配秘密,就在于这个 jar 包 。
从 spring-boot-autoconfigure 包的结构来看,它有一个 META-INF/spring.factories ,显然利用了 Spring Boot SPI,来自动装配其中的配置类 。

文章插图
下图是 spring-boot-autoconfigure 的 META-INF/spring.factories 文件的部分内容,可以看到其中注册了一长串会被自动加载的 AutoConfiguration 类 。

文章插图
以 RedisAutoConfiguration 为例,这个配置类中,会根据 @ConditionalXXX 中的条件去决定是否实例化对应的 Bean,实例化 Bean 所依赖的重要参数则通过 RedisProperties 传入 。
经验总结扩展阅读
- 10月28日3时42分新疆阿克苏地区沙雅县发生3.0级地震
- 10月28日4时34分新疆阿克苏地区温宿县发生3.0级地震
- 今年第22号台风“尼格”最强可达台风级 30日傍晚前后进入南海海面
- 红米note9pro评测最新_红米note9pro深度测评
- 空调一级能效与三级能效的区别是什么
- iOS 16.3.1正式版续航怎么样 iOS 16.3.1升级建议
- ipx7和ip68哪个更防水 哪个防水等级更高
- 10月28日今起三天陕西持续阴雨模式局地阵风6级 风寒效应明显需保暖
- EasyPoi大数据导入导出百万级实例
- Dubbo-聊聊通信模块设计