JDK的标准SPI对比dubbo的SPI

转载 http://blog.csdn.net/xiaoxufox/article/details/75117992#jdk%E7%9A%84%E6%A0%87%E5%87%86spi%E5%AF%B9%E6%AF%94dubbo%E7%9A%84spi

JDK的标准SPI对比dubbo的SPI
源码解析
getAdaptiveExtension
getAdaptiveExtensionClass
getExtensionClasses
loadFile从目录加载扩展实现
createAdaptiveExtensionClass
injectExtension
getActivateExtension
getExtension
createExtension
2种自定义扩展实现
Dubbo提供Adpative动态适配
自定义Adpative适配
dubbo框架的微内核+插件的机制,其中插件机制就是依赖ExtensionLoader来实现,可以说是dubbo的核心所在。通过插件机制解耦依赖来实现框架设计原则中的针对接口编程而不针对实现。
熟悉ExtensionLoader就熟悉了Dubbo的扩展机制。

JDK的标准SPI对比dubbo的SPI
JDK的SPI,新建接口,然后定义不同实现,然后/META-INF/services定义定义接口的全路径的文件,文件中写上接口的全部实现类,最后代码通过ServiceLoader加载,循环迭代得到所有实现类。标准SPI迭代时会加载所有实现,所以只希望加载某个的,就不现实了。
Dubbo的扩展SPI:
1. 单例,对于某个扩展,只会有一个ExtensionLoader;
2. 延迟加载,可以一次只获取想要的扩展点,一次获取想要的扩展点实现;
3. 对于扩展点的Ioc和Aop,就是一个扩展可以注入到另一个扩展中,也可以对一个扩展做wrap包装实现aop的功能;
4. 对于扩展点的调用,真正调用的时候才能确认具体使用的是那个实现。

源码解析
所有扩展必须加上SPI注解才能通过ExtensionLoader加载。对于一个扩展点只会加载一次,生成一个ExtensionLoader。通过ExtensionLoader.getExtensionLoader(class type)传入一个spi扩展返回一个ExtensionLoader实例。

/* 获取扩展点的ExtensionLoader,需要这里调用的时候需要自己确保线程安全,不过一般也不会有问题 /
public static ExtensionLoader getExtensionLoader(Class type) {
if (type == null)
throw new IllegalArgumentException(“Extension type == null”);
if(!type.isInterface()) {
throw new IllegalArgumentException(“Extension type(” + type + “) is not interface!”);
}
//必须加SPI注解
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) {
    //新建个ExtensionLoader返回
    EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
    loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
}
return loader;

}

private ExtensionLoader(Class

发布了49 篇原创文章 · 获赞 31 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/zengqiang1/article/details/79450801