在 Spring Boot 中,spring.factories
文件起着重要的作用,它是 Spring Boot 实现自动配置和扩展机制的关键部分。下面详细介绍 spring.factories
文件是如何被读取的。
spring.factories
文件的作用
spring.factories
文件位于类路径下的 META - INF
目录中,它是一个 properties 格式的文件,主要用于实现 Spring 的自动配置和扩展机制。该文件的键通常是接口或抽象类的全限定名,值是实现这些接口或继承这些抽象类的具体类的全限定名列表,多个类名之间用逗号分隔。
读取过程
1. 触发读取的时机
在 Spring Boot 应用启动过程中,SpringApplication
类的 run
方法会调用一系列初始化和配置的逻辑,其中会触发对 spring.factories
文件的读取操作。具体来说,当需要加载自动配置类、应用上下文初始化器、监听器等组件时,会从 spring.factories
文件中查找相应的实现类。
2. 使用 SpringFactoriesLoader
类读取文件
SpringFactoriesLoader
是 Spring 框架提供的一个工具类,专门用于从类路径下的 spring.factories
文件中加载工厂实现类。以下是读取过程的详细步骤:
- 获取类加载器:
SpringFactoriesLoader
会使用当前线程的上下文类加载器或者指定的类加载器来查找spring.factories
文件。
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- 查找所有
spring.factories
文件:通过类加载器的getResources
方法查找类路径下所有的META - INF/spring.factories
文件。
Enumeration<URL> urls = (classLoader != null ? classLoader.getResources("META - INF/spring.factories")
: ClassLoader.getSystemResources("META - INF/spring.factories"));
- 解析文件内容:对于找到的每个
spring.factories
文件,将其内容解析为一个Properties
对象。
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
- 根据键获取值:根据指定的工厂类型(键)从
Properties
对象中获取对应的实现类列表。
List<String> factoryImplementationNames = new ArrayList<>(Arrays.asList(
StringUtils.commaDelimitedListToStringArray(properties.getProperty(factoryTypeName))));
3. 示例代码
以下是一个简化的示例,展示了如何使用 SpringFactoriesLoader
读取 spring.factories
文件中的自动配置类:
import org.springframework.core.io.support.SpringFactoriesLoader;
import java.util.List;
public class SpringFactoriesLoaderExample {
public static void main(String[] args) {
// 获取自动配置类列表
List<String> autoConfigurationClasses = SpringFactoriesLoader.loadFactoryNames(
org.springframework.boot.autoconfigure.EnableAutoConfiguration.class,
Thread.currentThread().getContextClassLoader());
// 打印自动配置类列表
for (String className : autoConfigurationClasses) {
System.out.println(className);
}
}
}
总结
Spring Boot 通过 SpringFactoriesLoader
类在应用启动时查找并读取类路径下所有的 spring.factories
文件,根据不同的工厂类型(键)加载对应的实现类,从而实现自动配置和扩展机制。这种机制使得 Spring Boot 能够方便地集成各种第三方库和组件。