为什么dubbo不直接用jdk的spi机制,而是自己模仿实现了一个spi机制呢?
jdk的spi会在一次实例化所有实现,可能会比较耗时,而且有些可能用不到的实现类也会实例化,浪费资源而且没有选择。另外dubbo的spi增加了对扩展点IOC和AOP的支持,一个扩展点可以直接setter注入其他扩展点。这是jdk spi不支持的。
dubbo的spi文件定义在META-INF/dubbo/internal/路径下面和jdk的spi类似。但是dubbo的spi文件里面格式和jdkSPI有点不一样,格式是扩展名=全路径的类名,比如
threadlocal=com.alibaba.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory
lru=com.alibaba.dubbo.cache.support.lru.LruCacheFactory
jcache=com.alibaba.dubbo.cache.support.jcache.JCacheFactory
扩展名的作用是用来实现选择性的加载实现类。
dubbo的spi使用ExtensionLoader来实现。
//这个方法用户获取一个接口的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!"); } //从map从获取 ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type); if (loader == null) { //map中没有的时候会创建并缓存到map里面 EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type)); loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type); } return loader; }
//这个方法通过扩展名获取一个实现类
public T getExtension(String name) {
if (name == null || name.length() == 0)
throw new IllegalArgumentException("Extension name == null");
if ("true".equals(name)) {
return getDefaultExtension();
}
Holder<Object> holder = cachedInstances.get(name);
if (holder == null) {
//创建一个holder放到map里面 putIfAbsent保证了只有一个能放进去
cachedInstances.putIfAbsent(name, new Holder<Object>());
holder = cachedInstances.get(name);
}
Object instance = holder.get();
//双重判空加锁 创建一个单例的实现类对象
if (instance == null) {
synchronized (holder) {
instance = holder.get();
if (instance == null) {
instance = createExtension(name);
holder.set(instance);
}
}
}
return (T) instance;
}
private ExtensionLoader(Class<?> type) {
this.type = type;
//objectFactory的作用是为dubbo的IOC提供对象
objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
}
//获取一个扩展装饰类的对象 如果类没有用Adaptive注解就动态创建一个装饰类
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;
}
---------------------
作者:xujiajun955
来源:CSDN
原文:https://blog.csdn.net/xujiajun1994/article/details/80926323
版权声明:本文为博主原创文章,转载请附上博文链接!