SPI,即Service Provider Interface,为某个接口寻找服务实现的机制。
在springboot的启动类上面,我们一般会标注启动类注解@SpringBootApplication,而@SpringBootApplication是@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan等多个注解的合体,SPI机制的入口注解是@EnableAutoConfiguration,即springboot标注该注解,表示可以实现自动配置.
@EnableAutoConfiguration注解如下
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
我们可以看到,该注解import了一个EnableAutoConfigurationImportSelector类
该类有一个方法
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
该方法会通过SpringFactoriesLoader遍历整个ClassPath中所有jar包下的spring.factories文件。
所以我们自己开发的组件,如果想无缝融合到springboot中,就可以构建一个starter包,在该包中META-INF/spring.factories写入我们的组件的启动类的名称,springboot就可以通过SPI机制在启动的时候,自动加载并启动我们的组件。
SpringFactoriesLoader 源码解析可参考