SPI ,全称为 Service Provider Interface,是一种服务发现机制。它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类。
Dubbo、JDBC中都使用到了SPI机制,springboot也使用了spi机制,但是它并没有使用原生的,而是自己做了扩展。例子说明
工程结构
新建spi-interface工程,编写接口StuService和方法run
新建spi-girl类,引入spi-interface工程依赖,
StuGirlServiceImpl实现接口StuService
在resources文件夹下新建META-INF/services目录,然后新建文件名称是StuService的包名+接口名,文件内容放入他的实现类StuGirlServiceImpl
新建spi-boy类,引入spi-interface工程依赖,
StuBoyServiceImpl实现接口StuService
在resources文件夹下新建META-INF/services目录,然后新建文件名称是StuService的包名+接口名,文件内容放入他的实现类StuBoyServiceImpl
编写测试类,spi-test,引入spi-interface工程依赖,新建测试类SpiTest
运行代码,没输出任何东西。
引入spi-girl工程
再引入spi-boy工程
可以发现,我们需要那个只需要引入jar包就可以了,非常易于扩展。打开ServiceLoader.load源码,
路径是写死的所以必须在META-INF/services目录。加载过程,获取当前类的加载器,然后再调用load的重载方法
在调用 构造函数
通过next获取文件里的实现类
获取文件里的类名,通过反射获取到对象,调用方法
我们可以发现通过路径+文件名,找到所有放入的文件,然后放入configs对象里