總結(jié):?Protocolrefprotocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
首先會(huì)生成自適應(yīng)ExtensionFactory ,根據(jù)URL可適配的工廠包含兩個(gè)spi 和 spring厂僧;
然后才會(huì)真正的去生成Protocol的自適應(yīng)對象(代碼生成,并運(yùn)行時(shí)編譯),其可適配的對象就比較多了碴开,例如dubbo眷蚓,http等等
AAA 1 默認(rèn)首次執(zhí)行
ExtensionFactory 自適應(yīng)實(shí)現(xiàn)
private ExtensionLoader(Class type) {
? ? this.type = type;
? ? objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
}
META-INF/dubbo/internal/com.alibaba.dubbo.common.extension.ExtensionFactory
讀壤杼摹:指定包下的擴(kuò)展配置
ExtensionLoader.class.getClassLoader()
urls = classLoader.getResources(fileName);
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), "utf-8"));
META-INF/dubbo/internal/com.alibaba.dubbo.common.extension.ExtensionFactory
文件內(nèi)容:
spring=com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory
adaptive=com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory
spi=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory
1 解析url
spring=com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory
name=spring
line=com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory
Class clazz = Class.forName(line, true, classLoader);
interface
type=com.alibaba.dubbo.common.extension.ExtensionFactory
放入extensionClasses? cache: clazz = com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory
2 解析url
adaptive=com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory
name=adaptive? 包含SPI 和 Spring 兩個(gè)擴(kuò)展工廠
line=com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory
緩存adaptive--class不會(huì)放到extensionClasses 因?yàn)檫@個(gè)累就是 自適應(yīng)擴(kuò)展類
cachedAdaptiveClass= com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory
3 解析url
spi=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory
name=spi
line=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory
clazz=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory
extensionClasses.put(n, clazz);
AAA 2 自適應(yīng)擴(kuò)展類 使用該類:
com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory
@Adaptive? 自適應(yīng)擴(kuò)展類 代碼實(shí)現(xiàn)
public class AdaptiveExtensionFactory implements ExtensionFactory {
? ? private final List factories;
? ? public AdaptiveExtensionFactory() {
ExtensionLoader loader = ExtensionLoader.getExtensionLoader(ExtensionFactory.class);
? ? ? ? List list = new ArrayList();
? ? ? ? for (String name : loader.getSupportedExtensions()) {
? ? ? ? ? ? list.add(loader.getExtension(name));
? ? ? ? }
? ? ? ? factories = Collections.unmodifiableList(list);
? ? }
? ? public T getExtension(Class type, String name) {
? ? ? ? for (ExtensionFactory factory : factories) {
? ? ? ? ? ? T extension = factory.getExtension(type, name);
? ? ? ? ? ? if (extension != null) {
? ? ? ? ? ? ? ? return extension;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return null;
? ? }
}
自適應(yīng)擴(kuò)展工廠:包含spi,spring兩個(gè)擴(kuò)展工廠
BBB 其次才會(huì)繼續(xù)加載protocol:
對應(yīng)的文件內(nèi)容
registry=com.alibaba.dubbo.registry.integration.RegistryProtocol
dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol
filter=com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper
listener=com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper
mock=com.alibaba.dubbo.rpc.support.MockProtocol
injvm=com.alibaba.dubbo.rpc.protocol.injvm.InjvmProtocol
rmi=com.alibaba.dubbo.rpc.protocol.rmi.RmiProtocol
hessian=com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol
com.alibaba.dubbo.rpc.protocol.http.HttpProtocol
com.alibaba.dubbo.rpc.protocol.webservice.WebServiceProtocol
thrift=com.alibaba.dubbo.rpc.protocol.thrift.ThriftProtocol
memcached=memcom.alibaba.dubbo.rpc.protocol.memcached.MemcachedProtocol
java.lang.ClassNotFoundException: memcom.alibaba.dubbo.rpc.protocol.memcached.MemcachedProtocol
redis=com.alibaba.dubbo.rpc.protocol.redis.RedisProtocol
其中對應(yīng)的filter listener
filter=com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper
listener=com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper
會(huì)單獨(dú)緩存到Set> cachedWrapperClasses中
異常--->放置到exceptions中
// 完全沒有Adaptive方法窄驹,則不需要生成Adaptive類
//有類型為URL的參數(shù) 或者參數(shù)中有 getUrl()方法 -- 則可以創(chuàng)建 adaptive class 作者拼寫錯(cuò)誤為 adative
//生成具體的擴(kuò)展類實(shí)例
com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);
動(dòng)態(tài)編譯的java代碼文件
package com.alibaba.dubbo.rpc;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
public class Protocol$Adpative implements com.alibaba.dubbo.rpc.Protocol {
public void destroy() {throw new UnsupportedOperationException("method public abstract void com.alibaba.dubbo.rpc.Protocol.destroy() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");
}
public int getDefaultPort() {throw new UnsupportedOperationException("method public abstract int com.alibaba.dubbo.rpc.Protocol.getDefaultPort() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");
}
public com.alibaba.dubbo.rpc.Exporter export(com.alibaba.dubbo.rpc.Invoker arg0) throws com.alibaba.dubbo.rpc.Invoker {
if (arg0 == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");
if (arg0.getUrl() == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");com.alibaba.dubbo.common.URL url = arg0.getUrl();
String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );
if(extName == null) throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);
return extension.export(arg0);
}
public com.alibaba.dubbo.rpc.Invoker refer(java.lang.Class arg0, com.alibaba.dubbo.common.URL arg1) throws java.lang.Class {
if (arg1 == null) throw new IllegalArgumentException("url == null");
com.alibaba.dubbo.common.URL url = arg1;
String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );
if(extName == null) throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);
return extension.refer(arg0, arg1);
}
}