很好奇GROOVY是如何在JAVA语言的基础上平添了如此之多的强大功能和语言特性。翻看了一些GROOVY的源代码。语言的特性,离不开语言底层模 型的支持,在构建好自己的语言模型之后,接下来需要的就是形式化的东西,也就是语法,遵循语法编写代码,以用编译器构建出既定的语言模型体系下的字节码, 然后再JVM机上无差别于JAVA代码一样运行,我理解的Groovy就是这样。
GROOVY可以作为脚本来运行,即Script对象,也可以作为类似JAVA的Class来运行,不管是以Script方式运行还是说作为Class 方式。Groovy编译之后的类都是统一实现了GroovyObject接口。GroovyOjeject定义了invokeMethod方法,定义了属 性的GETTER和SETTER方法,定义了元类的GETTER和SETTER方法等利用GROOVY语言特性的基本方法。GroovyOjeject为 什么是接口不是类,原因在于Groovy最终编译成为java对象,JAVA对象不支持多继承,如果GroovyOjeject声明为类,而Groovy 的class也必须继承直接或者间接继承自GroovyObject,这样,声明Groovy类就不能继承自其它的JAVA类了,这样就直接影响了 GROOVY与JAVA的兼容性。
GROOVY语言模型中GroovyOjeject不是类,但是GROOVY提供了该接口的一个支持类GroovyObjectSupport,该类提 供了一个默认实现,供不需要继承自其它JAVA类来继承,比如语言内部的很多实现类以及由松散的脚本代码构建出来的Script类。
Script对象由开发人员的松散代码构建而来,编译器会将松散代码集中到Script定义的run方法中。其它的方法作为私有方法。开发人员编写松散 的groovy代码,相当于创建了一个继承自Script类的子类。脚本代码可以和运行时的环境作为整合,从上下文环境中读取信息。这一特性的实现基于组 合在Script中的Binding对象。Script的binding对象可以动态设置。GroovyObjectSupport默认实现中,属性的读 写都是针对元类的,Script重载了添加该实现,属性的读写都是针对binding对象(当然除了binding属性和metaclass两个属性本 身)。Script还重写了invokeMethod方法,当调用一个方法的时候,首先调用supper中的方法,当不存在该方法的时候,就从 binding中查询同名的闭包对象。如果查询到了执行该闭包。另外,Script提供了很多默认的实现的方法,比如 print,pringln,evaluate,run。
Binding类继承自GroovyObjectSupport,拥有Groovy类的通用特性,Bingding类本质上是对Map进行包装,默认情况 下,是采用LinkedHashMap来作为内部数据结构。放在Binding中的信息称之为variable。
MetaClass,MetaMethod,MetaProperty公共构建了Groovy的动态特性。
MetaClass定义了invokeMethod方法,定义了attribute,property,metaMethod的读写方法,以及 invokeMissingMethod,invokeMissingProperty方法。当然还包括initialize方法,该方法用以实现初始 化,在调用了改方法之后,就不能再向MetaClass中添加方法,属性了,只有在成功调用该方法之后才能够方位其中的属性方法。该方法建议在实现的时候 加锁,以保证原子性。
说道MetaClass就不得不提到MutableMetaClass,MutableMetaClass继承自MetaClass,额外定义了添加新实例方法,新元方法,新静态方法,新MetaBeanProperty。
MetaClassImpl为例来讲讲MetaClass的大致实现类结构。MetaClassImpl实现了MetaClass和 MutableMetaClass,也就是说MetaClassImpl是可以添加新方法的MetaClass类. MetaClassImpl包含了 MetaClassRegistry元类注册器的引用,一些标识信息,是否是GroovyObject对象,是否是Map对象
未完待续。。。
接下来,写一下关于Binding类,MetaClass,MetaMethod,MetaProperty