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

Is @SpringBootApplication able to find and AutoConfigure all dependency's beans without META-INF/spring.factories?

为什么我们在为 Spring 引导应用程序创建启动器时需要 META-INF/spring.factories?如果完全省略或留空怎么办?

目标应用程序的 @SpringBootApplication 不是

a combination of three annotations @Configuration (used for Java-based configuration), @ComponentScan (used for component scanning), and @EnableAutoConfiguration

在没有 META-INF/spring.factories?

帮助的情况下扫描所有内容并从所有启动器中找到所有 bean

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

还有另一层 - 您使用的许多库可能正在使用诸如“@AutoConfigureBefore”之类的注释来提供 spring 关于 bean 创建顺序的说明。组件扫描不会尊重这一点,如果某些依赖项试图从另一个用 @ConditionalOnMissingBean 注释的 bean 覆盖一个 bean(即仅在该 bean 不存在时才创建它),这可能会导致一些奇怪的行为。您可以很容易地结束名称冲突问题实际上首先创建了该 bean,然后也创建了覆盖 bean。

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

Doesn't the target application's @SpringBootApplication scan everything...

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

因此,如果您的应用程序的根包位于 com.sample.app(带有 class 注释并带有 @SpringBootApplication 的包),那么 spring 按照惯例引导仅扫描 bean在这个包和它下面的包中。这意味着它不会扫描任何第三方(假设它们不会被放置在 com.sample.app 中)。

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

所以自动配置模块(技术上用 META-INF/spring.factories 实现可以指定一个额外的地方(classes 用 @Configuration 注释)spring 引导将加载尽管事实上它们不在您的应用程序包下 或者换句话说,它们不遵守默认的组件扫描规则。

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