Spring.factories 原理

328 阅读3分钟

前言

Spring 框架的强大除了体现在其自身的功能强大,还提供了很多易扩展的能力,spring.factories 就是其中之一。

Spring 应用程序默认扫描主类所在的包路径,当你想要扫描其他路径,比如依赖的 jar 包中的类路径怎么办?

Spring.factories 就是解决方案之一

spring.factories是 Spring 框架中的一个重要配置文件,通常用于自动化配置扩展 Spring 应用程序。是 Spring Boot 自动配置机制的一部分,位于 META-INF 目录下。

通过 spring.factories 文件,Spring 可以在应用启动时自动加载和配置特定的类。

比如,你写了一个通用组件,当你想将通用组件引入到某项目使用,如何让这个组件能被正常扫描到(生效)?此时你就可以通过 spring.factories 来完成。

spring.factories 文件的常见用途:

  1. 自动配置:Spring Boot 使用 spring.factories 来定义哪些自动配置类应该被加载。例如,org.springframework.boot.autoconfigure.EnableAutoConfiguration 是一个常见的 key,用于指定自动配置类。
  2. 监听器:可以通过 spring.factories 注册 ApplicationListener,以便在应用程序事件发生时执行特定的逻辑。
  3. 环境后处理器:通过 spring.factories 注册 EnvironmentPostProcessor,可以在 Spring 环境准备好后进行自定义处理。
# 自动配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.CustomerAutoConfiguration

# 应用监听器
org.springframework.context.ApplicationListener=\
com.example.CustomerApplicationListener

# 环境后处理器
org.springframework.boot.env.EnvironmentPostProcessor=\
com.example.CustomerEnvironmentPostProcessor

原理

spring.factories 文件的工作原理主要依赖于 Spring 自身的配置加载机制。

工作原理

  1. 配置文件扫描:Spring Boot 在启动时会扫描类路径下的所有 META-INF/spring.factories 文件。
  2. 键值对映射:spring.factories 文件以键值对的形式定义了接口或抽象类与其实现类之间的映射关系。
  3. 反射机制:Spring 使用反射机制来实例化和加载这些配置文件中定义的类。
  4. 条件加载:Spring Boot 会根据条件注解(如 @ConditionalOnClass、@ConditionalOnProperty 等)判断是否应用这些配置。这使得应用程序能够根据当前环境和依赖自动调整配置。

通过这种机制,spring.factories 文件实现了模块化和可扩展的配置方式,使得 Spring 应用程序能够根据需要动态加载和配置组件,极大地提高了开发的灵活性效率

SPI 机制?

spring.factories 可以实现类似于 Java SPI 机制的功能,但它们的实现方式和使用场景有所不同。我们来对比看下差别:

Java SPI 机制

Java 的 SPI(Service Provider Interface)机制是一种服务发现机制,允许在运行时动态加载服务实现。

通过在 META-INF/services 目录下定义接口的实现类列表来实现。Java SPI 主要用于发现和加载实现类,而不涉及条件加载或复杂的配置逻辑。

Spring 的 spring.factories

spring.factories 文件是 Spring Boot 的一种配置机制,允许在应用启动时自动加载和配置组件。它的功能包括:

  1. 自动配置:通过定义自动配置类,Spring Boot 可以在应用启动时根据条件自动应用这些配置。
  2. 模块化扩展:允许开发者将功能模块化,并在需要时加载这些模块。
  3. 事件监听和环境后处理:可以注册 ApplicationListener 和 EnvironmentPostProcessor 等扩展点,以便在应用程序生命周期的不同阶段执行特定的逻辑。

虽然 spring.factories 和 Java SPI 都用于动态加载类,但 spring.factories 提供了更高层次的功能,包括条件加载和复杂的配置逻辑。这使得它在 Spring 应用程序中非常强大和灵活。

简言之:相较于 Java SPI 机制,spring.factories 提供了更加丰富的能力,在 扩展、解耦以及灵活性更加有力