Dubbo-SPI(service provider interface)源码解读
在看dubbo的服务暴露和注册的源码时,看到了这一块,由于SPI(service provider interface)算是Dubbo的核心,在此专门写一篇博客做专门解读(自己的理解),希望大家可以探讨,多提意见。
SPI(service providerinterface):也就是这里定义了一个接口,会有多个实现类,就如策略模式一样提供了策略的实现,但是没有提供策略的选择。
下面我们主要以这段代码来做解读:
private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension()
这里就需要getAdaptiveExtension()去动态的获取了。那我们就具体的去看一下ExtensionLoader这个类。
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 = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
}
return loader;
}
首先看获取实例对象方法,这里调用了EXTENSION_LOADERS.get(type),如果没有我们就需要初始化它,调用new ExtensionLoader<T>(type)如下:
private ExtensionLoader(Class<?> type) {
this.type = type;
objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
}
这里直到type == ExtensionFactory.class结束。然后返回一个loader实例。
下面主要看一下getAdaptiveExtension()方法:
public T getAdaptiveExtension() {
Object instance = cachedAdaptiveInstance.get();
if (instance == null) {
if(createAdaptiveInstanceError == null) {
synchronized (cachedAdaptiveInstance) {
instance = cachedAdaptiveInstance.get();
if (instance == null) {
try {
instance = createAdaptiveExtension();
cachedAdaptiveInstance.set(instance);
} catch (Throwable t) {
createAdaptiveInstanceError = t;
throw new IllegalStateException("fail to create adaptive instance: " + t.toString(), t);
}
}
}
}
else {
throw new IllegalStateException("fail to create adaptive instance: " + createAdaptiveInstanceError.toString(), createAdaptiveInstanceError);
}
}
return (T) instance;
}
首先介绍几个变量意思:
Holder<Map<String, Class<?>>> cachedClasses:所有实现了SPI接口的实现类实例化对象
Class<?> cachedAdaptiveClass:实现了SPI接口的实现类实例化对象中实现了@Adaptive注解的适配类
Set<Class<?>> cachedW