1.什么是SPI (面试题)
SPI全名Service Provider interface,翻译过来就是“服务提供接口”,再说简单就是提供某一个服务的接口, 提供给服务开发者或者服务生产商来进行实现。
Java SPI 是JDK内置的一种动态加载扩展点的实现。
这个机制在一般的业务代码中很少用到,但是在底层框架中却被大量使用,包括JDBC、Dubbo、Spring框架、日志接口中都有用到,不同的是有的使用Java原生的实现,有的框架则自己实现了一套SPI机制.
2.Spring SPI
Spring中的SPI相比于JDK原生的,它的功能更为强大,因为它可以替换的类型不仅仅局限于接口/抽象类,它可以是任何一个类,接口,注解;
正因为Spring SPI是支持替换注解类型的SPI,这个特性在Spring Boot中的自动装配有体现(EnableAutoConfiguration注解):
Spring的SPI文件是有规矩的,它需要放在工程的META-INF下,且文件名必须为spring.factories ,而文件的内容本质就是一个properties;如spring-boot-autoconfigure包下的META-INF/spring.factories文件,用于自动装配的;
Spring SPI加载spring.factories文件的操作是使用SpringFactoriesLoader,SpringFactoriesLoader它不仅可以加载声明的类的对象,而且可以直接把预先定义好的全限定名都取出来;
SpringFactoriesLoader#loadFactories加载spring.factories文件,最终会调用SpringFactoriesLoader#loadSpringFactories;
通过类加载器获取类路径下的FACTORIES_RESOURCE_LOCATION,之后获取到的资源路径,以properties的方式解析配置文件,其中配置文件的key为声明的类型,value为具体的实现的列表,最后将结果添加到缓存,其中缓存的key为类加载器,value为配置文件的内容;