总结: Protocolrefprotocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
首先会生成自适应ExtensionFactory ,根据URL可适配的工厂包含两个spi 和 spring;
然后才会真正的去生成Protocol的自适应对象(代码生成,并运行时编译),其可适配的对象就比较多了,例如dubbo,http等等
AAA 1 默认首次执行
ExtensionFactory 自适应实现
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
读取:指定包下的扩展配置
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
文件内容:
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 两个扩展工厂
line=com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory
缓存adaptive--class不会放到extensionClasses 因为这个累就是 自适应扩展类
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 自适应扩展类 使用该类:
com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory
@Adaptive 自适应扩展类 代码实现
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;
}
}
自适应扩展工厂:包含spi,spring两个扩展工厂
BBB 其次才会继续加载protocol:
对应的文件内容
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
其中对应的filter listener
filter=com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper
listener=com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper
会单独缓存到Set> cachedWrapperClasses中
异常--->放置到exceptions中
// 完全没有Adaptive方法,则不需要生成Adaptive类
//有类型为URL的参数 或者参数中有 getUrl()方法 -- 则可以创建 adaptive class 作者拼写错误为 adative
//生成具体的扩展类实例
com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);
动态编译的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);
}
}