![]() |
有腹肌的充值卡 · pycharm console 清屏 ...· 2 月前 · |
![]() |
谦和的手术刀 · 日期多选,月份多选,年份多选,季度多选,日历 ...· 1 年前 · |
![]() |
强健的烤面包 · Python 切片操作 - 掘金· 1 年前 · |
![]() |
火爆的草稿本 · 整理:C++中sprintf()函数的使用详 ...· 2 年前 · |
首先说明一下为什么要写这样一系列分析Groovy实现原理的博文。我之前在华为大数据部门曾维护过一份规则引擎的项目,该项目说白了就是一种DSL(Domain Specified Language),把用户的输入转化为一种可以执行的程序。让不懂编程语言的用户只定义一些规则说明便可以完成流程编写。后来由于部门调动,接触不到原来的规则引擎了,但是无意间发现Groovy这种DSL语言的实现机制和当时的规则引擎原理大体相当,所以便借分析Groovy的实现原理,缅怀当时负责的规则引擎吧。同时也希望给其他对规则引擎开发、DSL开发或者编程语言开发感兴趣的朋友一个参考,权当抛砖引玉了。
作为这一系列文章的第一篇,我们先做一些准备工作,为后来的原理分析做下铺垫。
要分析Groovy的实现原理,首先需要从源码构建Groovy,这样一边调试,一边看代码效率会高些。源码构建Groovy,需要JDK 7+,下载安装说明参考官网: https://docs.oracle.com/javase ,我使用的版本是:1.8.0_102。
PS C:\Users\jiang> java -version java version "1.8.0_102" Java(TM) SE Runtime Environment (build 1.8.0_102-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
Git是当下最流行的版本管理工具,我们需要利用Git下载Groovy的源代码。Git下载安装请参考官网: http://git-scm.com/ ,我使用的版本是:2.16.2。
PS C:\Users\jiang> git --version git version 2.16.2.windows.1
Groovy的源码托管在Apache的网站上,但是Github上有镜像,我们可以直接在Github镜像下载最新的主干版本,然后切换到最新的稳定版本2.4.14对应的TAG上。
PS C:\Users\jiang> cd D:\temp\Groovy\ git clone https://github.com/apache/groovy.git cd .\groovy\ PS D:\temp\Groovy\groovy> git checkout GROOVY_2_4_14
Groovy的编译需要Gradle工具,但是该工具不需要我们自己下载、配置,我们可以直接执行如下命令:
PS D:\temp\Groovy\groovy> .\gradlew.bat
由于墙的原因,下载需要使用VPN,搭建VPN的方法这里不再叙述。命令执行完毕会在
%USERPROFILE%\.gradle\wrapper\dists
目录下下载对应版本的gradle,其中Groovy 2.4.14版本对应的Gradle版本是Gradle 2.14.1。
执行下面命令,由源码编译Groovy:
.\gradlew.bat clean dist
编译完成后会在
target\distributions
目录下生成目标文件。
我们将
target\distributions\apache-groovy-binary-2.4.14.zip
文件中的内容解压到某个目录,比如说
C:\
,然后在%PATH%环境变量中添加
C:\groovy-2.4.14\bin
,并设置%GROOVY_HOME%环境变量为
C:\groovy-2.4.14
。然后我们新打开一个powershell验证Groovy是否安装成功:
PS C:\Users\jiang> cd D:\temp\Groovy\ PS D:\temp\Groovy> groovy.bat -v Groovy Version: 2.4.14 JVM: 1.8.0_102 Vendor: Oracle Corporation OS: Windows 10
为了更好的分析Groovy源码,我们需要一个IDE工具,具体是IDEA还是Eclipse或者其它都无所谓,看个人习惯,这里以IDEA为例。首先利用gradle生成IDEA项目:
PS D:\temp\Groovy> cd .\groovy\ PS D:\temp\Groovy\groovy> .\gradlew jarAll idea
这时候就可以使用IDEA导入groovy源码项目,进行分析研究了。
我们首先利用IDEA新建一个Groovy项目,写一个简单的Groovy程序,该程序会打印"Hello World":
package edu.jiangxin.test class Test { static void main(def args) { def mygreeting = "Hello World" println mygreeting }
我们知道Groovy是一种依赖于JVM的DSL,其先将 .groovy文件编译成 .class文件,然后调用JVM执行*.class文件,我们可以直接在IDEA中反编译该class文件,得到如下Java代码:
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) package edu.jiangxin.test; import groovy.lang.GroovyObject; import groovy.lang.MetaClass; import org.codehaus.groovy.runtime.callsite.CallSite; public class Test implements GroovyObject { public Test() { CallSite[] var1 = $getCallSiteArray(); super(); MetaClass var2 = this.$getStaticMetaClass(); this.metaClass = var2; public static void main(String... args) { CallSite[] var1 = $getCallSiteArray(); Object mygreeting = "Hello World"; var1[0].callStatic(Test.class, mygreeting); }
是不是看起来有些复杂?没关系我们会一点点搞懂它的。其实这里最关键的是三个函数
$getCallSiteArray()
,
$getStaticMetaClass()
以及
callStatic(Object, Object)
,我们会在之后的文章中逐步揭开他们的面纱。但是在这之前,我们先看下Groovy是如何将之前的
.groovy文件编译成对应的
.class文件的。
(未完待续)
本文参与 腾讯云自媒体分享计划 ,欢迎正在阅读的你也加入,一起分享。
![]() |
强健的烤面包 · Python 切片操作 - 掘金 1 年前 |
我来说两句