Dubbo SPI
什么是SPI?
SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。
Java SPI
public interface Color {
void color();
}
public class Yellow implements Color {
@Override
public void color() {
System.out.println("黄色");
}
}
public class Red implements Color {
@Override
public void color() {
System.out.println("红色");
}
}
然后再META-INF下新建services文件夹,新建一个文件为com.yyw.spi.Color,
com.yyw.spi.Yellow
com.yyw.spi.Red
public class SpiTest {
public static void main(String[] args) {
ServiceLoader<Color> serviceLoader = ServiceLoader.load(Color.class);
System.out.println("Java SPI");
serviceLoader.forEach(Color::color);
}
}
Java SPI
黄色
红色
Dubbo SPI
Dubbo SPI 的相关逻辑被封装在了 ExtensionLoader 类中,通过 ExtensionLoader,我们可以加载指定的实现类。Dubbo SPI 所需的配置文件需放置在 META-INF/dubbo 路径下,
yellow=com.yyw.spi.Yellow
red=com.yyw.spi.Red
需要在Color类上加@SPI注解。
public class DubboSpiTest {
public static void main(String[] args) {
ExtensionLoader<Color> extensionLoader = ExtensionLoader.getExtensionLoader(Color.class);
Color yellow = extensionLoader.getExtension("yellow");
yellow.color();
Color red = extensionLoader.getExtension("red");
red.color();
}
}
黄色
红色
ExtensionLoader#getExtensionLoader()
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
if (type == null)
throw new IllegalArgumentException("Extension type == null");
if (!type.isInterface()) {
throw new IllegalArgumentException("Extension type(" + type + ") is not interface!");
}
if (!withExtensionAnnotation(type)) {
throw new IllegalArgumentException("Extension type(" + type +
") is not extension, because WITHOUT @" + SPI.class.getSimpleName() + " Annotation!");
}
//从缓存中取实例,如果缓存中没有,则新建一个,并放入缓存中。
ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
if (loader == null) {
EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
loader = (