@SpringBootApplication 是否能够在没有 META-INF/spring.factories 的情况下找到并自动配置所有依赖项的 bean?

问题描述

为什么在为 Spring Boot 应用程序创建启动器时需要 meta-inf/spring.factories?如果完全省略或留空怎么办?

目标应用程序的 @SpringBootApplication 不是

三个注解的组合@Configuration(用于基于Java的 配置)、@ComponentScan(用于组件扫描)和 @EnableAutoConfiguration

在没有meta-inf/spring.factories帮助的情况下扫描所有内容并找到所有起始者的所有豆子?

解决方法

组件扫描将扫描您提供的包。从技术上讲,您也可以告诉它扫描所有依赖项的包,它会开始加载其中定义的任何 bean。如果您没有指定要扫描的任何包,那么 Spring 将使用应用注解的基础包,这很可能不包括在任何依赖库中定义的 bean。

还有另外一层——你使用的很多库可能使用“@AutoConfigureBefore”之类的注解来给出关于 bean 创建顺序的 spring 指令。组件扫描不会尊重这一点,如果某些依赖项试图覆盖来自另一个使用 @ConditionalOnMissingBean 注释的 bean(即仅在它不存在时创建此 bean),这可能会导致一些奇怪的行为。你很容易得到名称冲突问题,即首先创建该 bean,然后也创建了覆盖 bean。

所以答案似乎是否定的。你需要 spring.factories。

,

目标应用程序的@SpringBootApplication 不会扫描所有内容...

不,它不会扫描所有内容,因为如果扫描它可能需要大量时间和资源。想一想,为了理解扩展名为*.class的文件是否包含一个bean(例如用@Component注释的东西),它至少需要读取一个类并分析字节码甚至将其加载到内存中以通过反射检查注释。

因此,如果您的应用程序的根包在 com.sample.app(带有 @SpringBootApplication 注释的类的包)中,那么 Spring Boot 按照约定仅扫描此包中的 bean 及其下面的包。这意味着它不会扫描任何第三方(假设它们无论如何都不会被放置在 com.sample.app 中)。

现在确实可以更改组件扫描的规则,但同样,至少出于性能原因,您不想扫描所有内容。

因此自动配置模块(技术上用 META-INF/spring.factories 实现)可以指定一个额外的位置(用 @Configuration 注释的类),尽管它们没有放置在应用程序的包下,但 Spring Boot 将加载它们 或者,换句话说,他们不遵守默认的组件扫描规则。

此外,spring.factories 文件允许指定的不仅仅是自动配置规则,例如,您可以在那里指定环境后处理器,以及其他对您的应用程序有用的东西,可能最有益于应用基础架构,但仍然如此。