Spring Boot:自动配置原理及 spring.factories 的用法

此文章发布于 26 个月前,部分信息可能已经过时,请自行斟酌确认。

什么是 SPI 机制

SPI 全称 Service Provider Interface。多数开发人员可能不熟悉,因为这个是针对厂商或者插件的。在 java.util.ServiceLoader 的文档里有比较详细的介绍。

简单总结下 Java SPI 机制的思想。我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块的方案、xml解析模块、jdbc模块的方案等。面向的对象设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及了具体的实现类,就违反了可插拔的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。

Java SPI 提供这样的一种机制:为某个接口寻找服务的实现的,有点类似 IOC 思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制很重要。

Spring Boot 如何将依赖包中的 bean 注册到容器中?

Spring Boot 项目中,怎样将 pom.xml 文件里面添加的依赖中的 bean 注册到 Spring Boot 项目的 Spring 容器中呢?

你可能会首先想到使用 @ComponentScan 注解,遗憾的是 @ComponentScan 注解只能扫描 Spring Boot 项目包内的 bean 并注册到 Spring 容器中,项目依赖包中的 bean 不会被扫描和注册。此时,我们需要使用 @EnableAutoConfiguration 注解来注册项目依赖包中的 bean。而 spring.factories 文件,可用来记录项目包外需要注册的 bean 类名。

使用 spring.factories 文件有什么好处呢?假如我们封装了一个插件,该插件提供给其他开发人员使用。我们可以在 spring.factories 文件中指定需要自动注册到 Spring 容器的 bean 和一些配置信息。使用该插件的开发人员只需少许配置,甚至不进行任何配置也能正常使用。

实现原理

Spring Boot 在启动时会扫描外部引用 jar 包中的 META-INF/spring.factories 文件,将文件中配置的类型信息加载到 Spring 容器中(就是按照配置的类型信息,new 对象丢到 Spring 容器中),并执行类中定义的各种操作。

所以说,如果你想让 Spring Boot 自动将你的库的某个类的实例注册到 Spring 容器中,就需要按照其要求提供 META-INF/spring.factories 文件。

配置示例:

# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader

配置完成后在 IDEA 中即可看到类左边栏的图标:

20220301_144453.png

参考资料

http://shusheng007.top/2021/09/19/001-2/
https://www.hxstrive.com/article/947.htm
https://www.jianshu.com/p/7367dddab20d

最后修改:2022 年 03 月 01 日 02 : 58 PM
如果觉得我的文章对你有用,请随意赞赏

发表评论