Dubbo源码分析(六):Dubbo内核实现之动态编译
2016-05-07 15:10
609 查看
我们运行的java代码,一般都是编译之后的字节码。Dubbo为了实现基于spi思想的扩展特性,特别是能够灵活添加额外功能,对于扩展或者说是策略的选择这个叫做控制类也好设配类也好的类要能够动态生成。当然对应已知需求如Protocol, ProxyFactory他们的策略选择的设配类代码dubbo直接提供也无妨,但是dubbo作为一个高扩展性的框架,使得用户能够添加自己的需求,根据配置动态生成自己的设配类(控制类)代码,这样就需要在运行的时候去编译加载这个设配类(控制类)的代码。下面我们就是来了解下Dubbo的动态编译。
动态编译的实现的类图:
编译接口定义:
SPI注解表示如果没有配置,dubbo默认选用javassist编译源代码
接口方法compile第一个入参code,就是java的源代码
接口方法compile第二个入参classLoader,按理是类加载器用来加载编译后的字节码,其实没用到,都是根据当前线程或者调用方的classLoader加载的
AdaptiveCompiler是Compiler的设配类,它有类注解@Adaptive表示这个Compiler的设配类(控制类)不是动态编译生成的。
AdaptiveCompiler作用就是策略的选择,根据条件选择何种编译策略来编译动态生成的源代码。
AbstractCompiler为编译的抽象类,抽象出公用逻辑,这里它主要是利用正则匹配出源代码中的包名和类名后先在jvm中Class.forName看下是否存在,如果存在反回,不存在在执行编译与加载。
关于JavassistCompiler和JdkCompiler执行doCompile的过程都是利用Javassit和Jdk提供的相关api或者扩展接口实现的。
动态编译的实现的类图:
编译接口定义:
@SPI("javassist") public interface Compiler { Class<?> compile(String code, ClassLoaderclassLoader); }
SPI注解表示如果没有配置,dubbo默认选用javassist编译源代码
接口方法compile第一个入参code,就是java的源代码
接口方法compile第二个入参classLoader,按理是类加载器用来加载编译后的字节码,其实没用到,都是根据当前线程或者调用方的classLoader加载的
package com.alibaba.dubbo.common.compiler; import com.alibaba.dubbo.common.extension.SPI; /** * Compiler. (SPI, Singleton, ThreadSafe) * * @author william.liangf */ @SPI("javassist") public interface Compiler { <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span> * Compile java source code. <span style="white-space:pre"> </span> * <span style="white-space:pre"> </span> * @param code Java source code <span style="white-space:pre"> </span> * @param classLoader TODO <span style="white-space:pre"> </span> * @return Compiled class <span style="white-space:pre"> </span> */ <span style="white-space:pre"> </span>Class<?> compile(String code, ClassLoader classLoader); } SPI注解表示如果没有配置,dubbo默认选用javassist编译源代码 接口方法compile第一个入参code,就是java的源代码 接口方法compile第二个入参classLoader,按理是类加载器用来加载编译后的字节码,其实没用到,都是根据当前线程或者调用方的classLoader加载的 @Adaptive public class AdaptiveCompiler implements Compiler { private static volatile String DEFAULT_COMPILER; publicClass<?> compile(String code, ClassLoader classLoader) { Compiler compiler; ExtensionLoader<Compiler> loader= ExtensionLoader.getExtensionLoader(Compiler.class); String name = DEFAULT_COMPILER;// copyreference if (name !=null && name.length() > 0) { compiler =loader.getExtension(name); } else { compiler =loader.getDefaultExtension(); } return compiler.compile(code, classLoader); } }
AdaptiveCompiler是Compiler的设配类,它有类注解@Adaptive表示这个Compiler的设配类(控制类)不是动态编译生成的。
AdaptiveCompiler作用就是策略的选择,根据条件选择何种编译策略来编译动态生成的源代码。
AbstractCompiler为编译的抽象类,抽象出公用逻辑,这里它主要是利用正则匹配出源代码中的包名和类名后先在jvm中Class.forName看下是否存在,如果存在反回,不存在在执行编译与加载。
关于JavassistCompiler和JdkCompiler执行doCompile的过程都是利用Javassit和Jdk提供的相关api或者扩展接口实现的。
相关文章推荐
- 《java入门第一季》之面向对象综合小案例
- 如何正确查看Linux机器内存使用情况
- uvalive3305(双调欧几里德旅行问题)
- isset & empty
- 大数据(Big Data)扫盲
- python学习笔记(SMTP邮件发送)
- bzoj4576 [Usaco2016 Open]262144
- Binder学习笔记(四)—— ServiceManager如何响应checkService请求
- hive笔记-----用户定义函数
- 斯坦福大学公开课 编程方法学 Breakout 解题思路
- request.getRequestURI(),request.getRequestURL(),request.getQueryString()区别
- spring-data-mongo-1.8.2.RELEASE连接mongodb副本集备忘
- 二分图匹配(匈牙利算法)
- 从12306信息泄露了解何为黑客撞库拖库洗库
- linux系统中vi/vim 使用方法讲解
- 输入 和 运算符
- js实现上传图片及时预览
- 使用JAVA中的动态代理实现数据库连接池
- .Net 4.5中的HttpClient使用方法
- Objective C中数组排序几种情况的总结