【开始解析最后一行代码 ExtensionLoader.getAdaptiveExtension()】
ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class); final Protocol dubboProtocol = loader.getExtension("dubbo"); final Protocol adaptiveExtension = loader.getAdaptiveExtension();
【getAdaptiveExtension()调用结果】
ExtesionLoader.getAdaptiveExtension() --createAdaptiveExtension() ----getAdaptiveExtensionClass() //从spi文件中查找实现类上有@Adaptive注解的类 ------getExtensionClasses() --------loadExtensionClasses() ----------loadFile(Map<String, Class<?>> extensionClasses, String dir) //第三行代码的重点,如果从spi文件中没找到实现类上有@Adaptive的类,则动态创建类 ------createAdaptiveExtensionClass()
【 createAdaptiveExtensionClass()源码 】
private Class<?> createAdaptiveExtensionClass() { String code = createAdaptiveExtensionClassCode(); ClassLoader classLoader = findClassLoader(); com.alibaba.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.common.compiler.Compiler.class).getAdaptiveExtension(); return compiler.compile(code, classLoader); }
【createAdaptiveExtensionClassCode()方法 】
createAdaptiveExtensionClassCode()方法中会判断:如果一个类中没有@Adaptive注解,直接抛出IllegalStateException异常;如果类有含@Adaptive注解的方法,则为其构造代码;如果类没有含@Adaptive注解的方法的,直接抛出UnsupportedOperationException异常,见下图
【含有@Adaptive注解的方法构造的Protocol$Adaptive对象如下】
package com.alibaba.dubbo.rpc; import com.alibaba.dubbo.common.extension.ExtensionLoader; public class Protocol$Adaptive 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.Invoker refer(java.lang.Class arg0, com.alibaba.dubbo.common.URL arg1) throws com.alibaba.dubbo.rpc.RpcException { 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); } public com.alibaba.dubbo.rpc.Exporter export(com.alibaba.dubbo.rpc.Invoker arg0) throws com.alibaba.dubbo.rpc.RpcException { 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); } }
【获取Compiler装饰类】
com.alibaba.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
【com.alibaba.dubbo.common.compiler.Compiler 接口】
@SPI 注解的默认值为"javassist",根据上一节的经验,默认获取的Compiler接口的实现类是META-INF/dubbo/internal/com.alibaba.dubbo.common.compiler.Compiler文件中的key为javassist的实现类,如下:
扫描二维码关注公众号,回复:
3095981 查看本文章
adaptive=com.alibaba.dubbo.common.compiler.support.AdaptiveCompiler jdk=com.alibaba.dubbo.common.compiler.support.JdkCompiler javassist=com.alibaba.dubbo.common.compiler.support.JavassistCompiler