dubbo扩展加载机制细节
ps:上篇服务器启动有点说错了,文章末尾说一个服务会启动一个nettyserver,实际上只有第一个会创建,然后会缓存起来,也就是说整个应用启动只会创一个nettyserver,说明dubbo里是单一连接的。
接下来分析一些扩展加载器的细节
进入方法看看,返回该类对应的扩展加载器
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
//不能为空,必须是接口,该类型必须存在SPI注解
if (type == null) {
throw new IllegalArgumentException("Extension type == null");
}
if (!type.isInterface()) {
throw new IllegalArgumentException("Extension type (" + type + ") is not an interface!");
}
if (!withExtensionAnnotation(type)) {
throw new IllegalArgumentException("Extension type (" + type +
") is not an extension, because it is NOT annotated with @" + SPI.class.getSimpleName() + "!");
}
//从EXTENSION_LOADERS 中检查是否存在这个类型的加载器
ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
//如果不存在这个加载器
if (loader == null) {
//创建这个加载器,并放到EXTENSION_LOADERS缓存起来
EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
}
//返回这个类型的加载器
return loader;
}
然后调用getAdaptiveExtension,获取适配的扩展,缓存为空,创建适配的扩展
看看怎么创建适配的扩展
主要逻辑是:获取适配的扩展,然后实例化,并进行inject,看看怎么获取适配的扩展的:
(1)从缓存中获取扩展类,没有,加载扩展的类
1.1继续看看怎么加载的,先缓存默认名称到缓存,
获取默认名称逻辑: 从该类型(ProxyFactory)的spi注解得到默认名称
默认是javassist:
1.2 返回加载的扩展类,有三个策略(
),从这三个目录里加载对应文件,读取里面的扩展类,这里有两个,一个jdk,一个是javassist
(2)再回到这个方法,如果缓存适配扩展类还是空,代表没有适配的扩展类,就通过自己生成,并编译成类
生成适配扩展类
我们重点看看这个生成的类的getInvoker方法:
重点最后两行,本质是调用ProxyFactory的扩展类去加载扩展,然后调用实际扩展类的getInvoker方法
org.apache.dubbo.rpc.ProxyFactory extension = (org.apache.dubbo.rpc.ProxyFactory)ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.ProxyFactory.class).getExtension(extName);
return extension.getInvoker(arg0, arg1, arg2);