spring.factories配置文件解析,bean预加载

395 阅读2分钟

springboot核心基础之spring.factories机制

引言

在java spring cloud项目中,我们常常会在子模块中创建公共方法,那么在另外一个子模块中,需要加载配置文件的时候,往往Spring Boot 自动扫描包的时候,只会扫描自己模块下的类。这个是springboot约定俗成的内容。

抛出问题

如果想要被Spring容器管理的Bean的路径不再Spring Boot 的包扫描路径下,怎么办呢?也就是如何去加载第三方的Bean 呢?

目前较通用的方式有2种,一是使用注解进行实例化,而是使用spring.factories机制。

这里我们使用Swagger的配置来做实验。

 首先一个Swagger的配置类:SwaggerConfig,工程结构如下:

image.png

发现我的SwaggerConfig 类和 SpringBoot 的启动类ConfigApplication.java 不在同一级目录下,按照springboot启动机制,以当Spring Boot 自动扫描包的时候,是扫描不到我的SwaggerConfig 的配置的,也就在控制台没有Swagger的打印的信息:

所以这时候我如果想要把SwaggerConfig 加载到Spring容器中的话 要怎么办呢?下面介绍上面提到的2种方式:

方法解决

方法一:在Spring Boot Application 主类上使用@Import注解。

image.png

关于@Import 注解有不懂的同学,建议自行学习。

方法二:创建spring.factories文件

现在我们将其改造一下,采用spring.factories 的方式去加载SwaggerConfig类,在resources目录下新建一个META-INF 的目录,然后在

新建一个spring.factories 的文件,里面的内容为:

```
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.heima.common.exception.ExceptionCatch,\
  com.heima.common.swagger.SwaggerConfiguration,\
  com.heima.common.swagger.Swagger2Configuration
```

spring.factories的是通过Properties解析得到的,所以我们在写文件中的内容都是按照这种方式配置的。

image.png

到这就完成了加载一个Spring 不能扫描到的一个类,他可以是第三方的,也可以是自己写的,只要是Spring Boot 默认扫描路径不能够扫描到,都可以使用这种方式去加载。

内部原理机制

Spring.Factories这种机制实际上是仿照java中的SPI扩展机制实现的。

Spring Boot 中的SPI 机制

在Spring boot 中也有一种类似的加载机制,它在
META-INFO/spring.factories文件中配置接口的实现类名称,然后在程序中读取这些配置文件并实例化。

这种自定义的SPI 机制就是Spring Boot Starter 实现的基础。