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(" String 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/类名 路径下面的所有集合

原文地址:https://www.cnblogs.com/gtaxmjld/p/9784991.html