ExtentionLoader
最近一段时间在看dubbo,看了一段时间,不知从哪开始,网上看到**源码,问了同事,还不错,买了99/年的权限。
之前就听同事说dubbo对扩张非常好,看了源码发现,核心类就是ExtentionLoader。
1.dubbo包装的spi和jdk本身spi比较
1.1 jdk会一次性实例化所有实现,初始化很耗时,如果没用到,浪费资源。
1.2jdk在加载扩展失败时定位问题很繁琐。
1.3增加IOC,可以自动注入参数。
2.主要用法源码解析
2.1 getAdaptiveExtension
ExtensionLoader.getExtensionLoader(ExporterListener.class)
关键代码
objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
首先实例化ExtensionFactory
objectFactory实例化来源路径:META-INF/dubbo/internal/类名,META-INF/dubbo/类名,META-INF/services/类名
如果ExtensionLoader,getAdaptiveExtension 获取时,的type不在这些路径里,或者这些类没有@Adaptive 标签,ExtensionFactory会自动创建,
创建代码和逻辑:
接口名$Adaptive implements 接口名
如果方法名前没有Adaptive,该方法是空实现
如果有Adaptive,如果参数类型是URL,直接给url赋值 org.apache.dubbo.common.URL url = arg1;
如果参数没有URL类型,参数的方法中是否是get**返回URL的,用这个
如果参数类型是:org.apache.dubbo.rpc.Invocation
方法中加:String methodName = arg1.getMethodName();
如果方法的注解 Adaptive的value为空,默认为type的名称,单词用“.”连接,根据value值 ,有下面判断
for (int i = value.length - 1; i >= 0; --i) {
if (i == value.length - 1) {
if (null != defaultExtName) {
if (!"protocol".equals(value[i]))
if (hasInvocation)
getNameCode = String.format("url.getMethodParameter(methodName, \"%s\", \"%s\")", value[i], defaultExtName);
else
getNameCode = String.format("url.getParameter(\"%s\", \"%s\")", value[i], defaultExtName);
else
getNameCode = String.format("( url.getProtocol() == null ? \"%s\" : url.getProtocol() )", defaultExtName);
} else {
if (!"protocol".equals(value[i]))
if (hasInvocation)
getNameCode = String.format("url.getMethodParameter(methodName, \"%s\", \"%s\")", value[i], defaultExtName);
else
getNameCode = String.format("url.getParameter(\"%s\")", value[i]);
else
getNameCode = "url.getProtocol()";
}
} else {
if (!"protocol".equals(value[i]))
if (hasInvocation)
getNameCode = String.format("url.getMethodParameter(methodName, \"%s\", \"%s\")", value[i], defaultExtName);
else
getNameCode = String.format("url.getParameter(\"%s\", %s)", value[i], getNameCode);
else
getNameCode = String.format("url.getProtocol() == null ? (%s) : url.getProtocol()", getNameCode);
}
}
code.append("\nString extName = ").append(getNameCode).append(";");
决定 String extName =什么,然后加 类 extension= (类)ExtensionLoader.getExtensionLoader(类).getExtension(extName);
然后有返回值的执行 extension.方法名(参数);
2.2
2.3 cachedClasses META-INF/dubbo/internal/类名,META-INF/dubbo/类名,META-INF/services/类名 路径下面的所有集合