JAVA SPI
1 介绍
- SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。SPI 实际上是 “基于接口的编程+策略模式+配置文件” 组合实现的动态加载机制。
- 在实际生产中,我们就可以使用java spi面向接口编程,实现动态可插拔。
2 SPI 实现
2.1 定义一个接口
package spi.test;
public abstract class BaseUdf extends ScalarFunction {
// udf name
public abstract String name();
}
继承接口
package spi.test;
public class TestUdf extends BaseUdf {
// udf name
public String name() {
return "testUdf";
};
}
2.2 功能实现
按需求实现接口功能
2.3 resources 创建配置文件
- resources 下创建META-INF.services创建 spi.test.BaseUdf 文件,注意事BaseUdf的包名+类名
- 在spi.test.BaseUdf文件中配置需要动态加载的子类
# 注意 也是包名 + 类名
spi.tes.TestUdf
2.4 动态加载
public static void main(String[] args) {
ServiceLoader<BaseUdf> load = ServiceLoader.load(BaseUdf.class);
for (BaseUdf udf: load) {
System.out.println(udf.name());
}
}
3. 实现原理
- SErviceLoader 通过 BaseUdf.class 报名+类名(spi.test.BaseUdf) 到META-INF.services目录下加载spi.test.BaseUdf文件
- 解析spi.test.BaseUdf文件,一行一行读取获取类全路径
- 遍历ppClassLoader动态加载类并返回