写在前面
spring.factories方案解决了在Spring Boot项目中,不能被默认路径扫描的情况,当然@Import注解也是一种解决方案。
spring.factories文件采用KV的形式记录了需要注册到Spring容器中的Bean的类名,SpringBoot会遍历整个项目CLASSPAHT下ClassLoader中所有JAR包下的spring.factories文件,将记录的Bean注入到Spring上下文中,与JAVA-SPI机制类似。
@ComponentScan注解的作用是扫描@SpringBootApplication注解的Application类(项目的入口类)所在的包下(当然扫描类路径是可以配置的),所有被@component注解(或拓展了@component的注解)标记的Bean,并注册到spring容器中。
使用场景
在实际的项目中,无论使用@Import还是@ComponentScan都可以将默认路径下或者以外的Bean注册到Spring上下文中,为什么还使用spring.factories文件呢?想想下面的场景:
当引用第三方依赖时,哪些类需要注册到Spring上下文中,哪些类不需要注册?显然使用@Import和@ComponentScan都不是最优解决方案,如果第三方的依赖已封装好,调用者无需关心如何注入,是不是很友好呢?这时候就产生了spring.factories方案。比如很多内置的场景启动器spring-boot-starter-XXX,都是采用这种方案。
实现原理
spring-core包里的SpringFactoriesLoader类,实现了检索 META-INF/spring.factories文件,并获取指定接口的配置的功能。在这个类中定义了两个对外的方法:
- loadFactories:根据接口类获取其实现类的实例,这个方法返回的是对象列表;
- loadFactoryNames:根据接口获取其接口类的名称,这个方法返回的是类名的列表。
上面的两个方法的关键都是从指定的ClassLoader中获取 spring.factories 文件,并解析得到类名列表,然后将这些类注册到Spring的上下文中。
spring.factories
在spring-boot-autoconfigure-2.4.2.jar中的spring.factories 中有各种KEY的使用,不同的KEY有不同的使用场景,KEY声明的是一个个的接口,VALUE是对应的实现:
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
#

本文详细介绍了Spring Boot中spring.factories文件的作用和使用场景,它允许第三方依赖无需关心如何注入,即可自动注册到Spring容器。通过SpringFactoriesLoader类,Spring Boot读取并加载META-INF/spring.factories中的配置,实现类的自动注册。同时,文章列举了多个配置示例,展示了不同场景下的配置键值对,如AutoConfiguration、FailureAnalyzers等,揭示了Spring Boot的自动化配置机制。
最低0.47元/天 解锁文章
2509





