Dubbo 系列JDK SPI 原理解析
什么是SPI
SPI,全称为 Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的接口集合。简单来说,SPI就是一种动态加载机制。在SPI中,我们定义了一个接口,这个接口可以有多种实现方式,而这些实现方式,都是以文件的形式存在。当我们需要某一个接口的实现时,我们只要定义好了这个接口,然后通过SPI机制去扫描相关的实现类,找到我们需要的一个实现,然后加载进内存,就可以直接使用了。
JDK SPI
在JDK中,SPI是通过 java.util.ServiceLoader实现的。
在SPI机制中,如果我们想要自定义一个服务,我们需要做以下三件事情:
- 创建服务接口
- 创建服务提供者接口以及服务提供者实现类(可以有多个)
- 在供应者实现类同一路径下创建 META-INF/services/服务接口 全限定名 的文件,文件中包含服务提供者类名
下面的示例提供了一个从计算器实现中获取服务的示例,该计算器将提供添加、减少、乘法和除法操作。
- 创建服务接口
package com.example.calculator;
public interface Calculation {
int calculate(int a, int b);
}
- 创建服务提供者接口以及服务提供者实现类
package com.example.calculator;
public interface CalculationProvider {
Calculation getCalculation();
}
接着,我们有四个实现了Calculation接口的类,对应四种不同的数学运算:
package com.example.plus;
import com.example.calculator.Calculation;
public class PlusCalculation implements Calculation {
@Override
public int calculate(int a, int b) {
return a + b;
}
}
package com.example.minus;
import com.example.calculator.Calculation;
public class MinusCalculation implements Calculation {
@Override
public int calculate(int a, int b) {
return a - b;
}
}
package com.example.mul;
import com.example.calculator.Calculation;
public class MulCalculation implements Calculation {
@Override
public int calculate(int a, int b) {
return a * b;
}
}
package com.example.div;
import com.example.calculator.Calculation;
public class DivCalculation implements Calculation {
@Override
public int calculate(int a, int b) {
if (b == 0) {
throw new IllegalArgumentException("Cannot divide by 0!");
}
return a / b;
}
}
最后,我们需要在相同路径下创建 META-INF/services/com.example.calculator.Calculation 文件,其内容分别为类名。
com.example.plus.PlusCalculation
com.example.minus.MinusCalculation
com.example.mul.MulCalculation
com.example.div.DivCalculation
- 使用ServiceLoader获取服务
import java.util.ServiceLoader;
import com.example.calculator.Calculation;
import com.example.calculator.CalculationProvider;
public class Main {
public static void main(String[] args) {
ServiceLoader<CalculationProvider> calculationProviders = ServiceLoader.load(CalculationProvider.class);
for (CalculationProvider calculationProvider : calculationProviders) {
Calculation calculation = calculationProvider.getCalculation();
System.out.println(calculation.calculate(4, 2));
}
}
}
运行结果:
6
2
8
2
总结
JDK SPI是一些列简单而有效的Java SPI实现方式之一,也是最常用的一种。这种方法不需要繁琐复杂的配置,只需要在相应的路径下把服务提供者实现类的类名写到文件中。只有在需要调整的时候,才需要添加更多的服务提供者实现。
通过使用JDK SPI,我们可以更好地脱离依赖,更好地解耦。同时,我们也可以在不破坏依赖关系的情况下,扩展我们的程序。
通过了解更多关于Java实现SPI的知识,我们可以更好的理解和使用Dubbo。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Dubbo 系列JDK SPI 原理解析 - Python技术站