动态语言Groovy核心原理

groovy 与java

1、groovy 与java 最终都是以字节码的方式在JVM 上面执行。groovy并没有突破jvm的字节码语法机制.
2、groovy的脚本片段、groovy class类最终都会编译成java class字节码,所以java和groovy天然具有互操作性.
3、groovy和java的编译和加载步骤是一样的,差异是groovy显式支持运行时编译和动态加载(其实java也可以).

groovy源代码的编译过程

和java一样,groovy支持将.groovy源代码编译成.class字节码文件(预编译模式),同时又支持在运行时加载并编译.groovy源文件(直接调用模式).
在这里插入图片描述

预编译模式

java用javac编译源文件,groovy预编译需要使用groovyc命令编译.groovyc编译的字节码完全符合jvm的标准,并可以反编译成.java文件.

直接调用模型

直接调用
在这里插入图片描述

Groovy的编译加载过程

groovy的编译过程与java的过程一样,预编译过程和直接调用过程一样.差异在于javac和groovyc编译都生成了.class字节码文件,运行时通过标准的ClassLoader加载类文件,而直接调用则是通过GroovyClassLoader加载源文件,并在内存中直接加载二进制流.

Groovy脚本编译原理

与严格要求class对象定义的java语言不同,groovy同时支持代码片段(表达式、函数定义)和完整的class类定义,并且可以实时加载运行这些源代码.这里实现的技术主要是自动化封装和动态编译.具体的规则如下.

  1. 表达式片段
    表达式代码会被编译到groovy.lang.Script子对象的run()方法下,class 的名称与文件名称一样(或直接命名为Script
    1,Script2…)

  2. 函数定义片段
    函数定义会被编译成groovy.lang.Script的子对象的方法.可以通过Script.invokeMethod()调用(实际是GroovyObject提供的方法).

  3. 一个或多个class声明
    groovy 只有一个class 声明,那么生成的class 与java 定义生成的class 一样.groovy 有多个class 声明,每个class 定义都会生产类,第一个类里面还有有一个main 方法定义.

  4. 混合class声明和表达式片段
    groovy 里面含有class 声明也含有 脚本代码,脚本代码会变成main class 执行。class 定义的类会生成class 对象

定制groovy编译效果

CompilerConfiguration,设置groovy 编译选项,比如设置基类,设置默认导包,安全校验等等等,其他自定义操作

Groovy动态方法执行原理

在一个Groovy应用中,会调用三种对象:

  • POJO 普通java对象
    OneClass extends java.lang.Object
  • POGO 普通Groovy对象
    OneClass extends java.lang.Object implements groovy.lang.GroovyObject
  • Groovy拦截器
    OneClass extends java.lang.Object implements groovy.lang.GroovyInterceptable

GroovyInterceptable中没有抽象方法,它只是起标记作用的接口.
在Groovy中动态地注入方法、调用方法、属性就是使用元类metaClass来完成的(类似于Java的反射机制),请求的方法会被委托到这个类。

与java编译成字节码时处理方法调用不同,Groovy编译时对方法调用通用都是通过invokeMethod实现,这样提供了极强的动态方法植入能力.
所有groovy 脚本生成的class 都会实现 GroovyObject 接口,Groovy 里面所有方法调用都会通过 invokeMethod 来调用.

MetaClass and MetaClassRegistry

  1. MetaClassRegistry 存储了所有MetaClass 包含java 的,groovy 的
  2. GroovyObject 的invokeMethod 实际是由MetaClass 来执行的

TODO replace this pictrue

Groovy方法执行流程

动态执行过程

执行groovy的方法

  • GroovyShell 关注独立的 Script (一个Script) 代码片段,没有class,没有依赖.
  • GroovyScriptEngine 关注多个 Script 有依赖,处理 script 的依赖及重新加载.
  • GroovyClassLoader 用于动态编译及加载 Groovy 类.
    底层GroovyShell,GroovyScriptEngine都是依赖GroovyClassLoader实现字节码的加载.差异是编译过程不一样.

参考文档

  1. Gradle | 集成groovy原理
  2. Groovy in Action
  3. java编译与反编译
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值