歡迎和大家交流技術相關問題:
郵箱: jiangxinnju@163.com
博客園地址: http://www.cnblogs.com/jiangxinnju
GitHub地址: https://github.com/jiangxincode
知乎地址: https://www.zhihu.com/people/jiangxinnju
首先說明一下為什么要寫這樣一系列分析Groovy實現原理的博文。我之前在華為大數據部門曾維護過一份規則引擎的項目,該項目說白了就是一種DSL(Domain Specified Language),把用戶的輸入轉化為一種可以執行的程序。讓不懂編程語言的用戶只定義一些規則說明便可以完成流程編寫。后來由於部門調動,接觸不到原來的規則引擎了,但是無意間發現Groovy這種DSL語言的實現機制和當時的規則引擎原理大體相當,所以便借分析Groovy的實現原理,緬懷當時負責的規則引擎吧。同時也希望給其他對規則引擎開發、DSL開發或者編程語言開發感興趣的朋友一個參考,權當拋磚引玉了。
作為這一系列文章的第一篇,我們先做一些准備工作,為后來的原理分析做下鋪墊。
安裝JDK
要分析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是當下最流行的版本管理工具,我們需要利用Git下載Groovy的源代碼。Git下載安裝請參考官網:http://git-scm.com/,我使用的版本是:2.16.2。
PS C:\Users\jiang> git --version
git version 2.16.2.windows.1
下載Groovy源碼
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
准備Gradle工具
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
執行下面命令,由源碼編譯Groovy:
.\gradlew.bat clean dist
編譯完成后會在target\distributions目錄下生成目標文件。
安裝編譯后的Groovy
我們將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源碼導入IDEA
為了更好的分析Groovy源碼,我們需要一個IDE工具,具體是IDEA還是Eclipse或者其它都無所謂,看個人習慣,這里以IDEA為例。首先利用gradle生成IDEA項目:
PS D:\temp\Groovy> cd .\groovy\
PS D:\temp\Groovy\groovy> .\gradlew jarAll idea
這時候就可以使用IDEA導入groovy源碼項目,進行分析研究了。
執行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文件的。
(未完待續)
