设为首页 加入收藏

TOP

Groovy深入探索——Groovy的ClassLoader体系
2014-11-23 19:49:06 来源: 作者: 【 】 浏览:24
Tags:Groovy 深入 探索 ClassLoader 体系

Groovy中定义了不少ClassLoader,本文将介绍其中绝大多数Groovy脚本都会涉及到的,也是最主要的3个ClassLoader:RootLoader、GroovyClassLoader和GroovyClassLoader.InnerLoader。


注:以下分析的Groovy源代码来自Groovy 2.1.3。


Java的ClassLoader


顾名思义,Java的ClassLoader就是类的装载器,它使JVM可以动态的载入Java类,JVM并不需要知道从什么地方(本地文件、网络等)载入Java类,这些都由ClassLoader完成。


可以说,ClassLoader是Class的命名空间。同一个名字的类可以由多个ClassLoader载入,由不同ClassLoader载入的相同名字的类将被认为是不同的类;而同一个ClassLoader对同一个名字的类只能载入一次。


Java的ClassLoader有一个著名的双亲委派模型(Parent Delegation Model):除了Bootstrap ClassLoader外,每个ClassLoader都有一个parent的ClassLoader,沿着parent最终会追索到Bootstrap ClassLoader;当一个ClassLoader要载入一个类时,会首先委派给parent,如果parent能载入这个类,则返回,否则这个ClassLoader才会尝试去载入这个类。


Java的ClassLoader体系如下,其中箭头指向的是该ClassLoader的parent:


更多关于Java的ClassLoader的信息请参考以下资料:


Groovy的ClassLoader


我们首先通过一个脚本来看一下,一个Groovy脚本的ClassLoader以及它的祖先们分别是什么:


输出如下:


我们从而得出Groovy的ClassLoader体系:


下面我们分别介绍一下RootLoader、GroovyClassLoader和GroovyClassLoader.InnerLoader。


Groovy脚本启动过程


要介绍RootLoader前,我们需要介绍一下Groovy脚本的启动过程。


当我们在命令行输入“groovy SomeScript”来运行脚本时,调用的是shell脚本$GROOVY_HOME/bin/groovy:


其中startGroovy定义在$GROOVY_HOME/bin/startGroovy中:


我们可以发现,这里其实是通过java启动了org.codehaus.groovy.tools.GroovyStarter,然后把“--main groovy.ui.GroovyMain”作为参数传给GroovyStarter,最后又把SomeScript作为参数传给GroovyMain。注意,这里只把$GROOVY_HOME/lib/groovy-2.1.3.jar作为classpath参数传给了JVM,而不包含Groovy依赖的第三方jar包。


我们来看一下GroovyStarter的源代码(其中省略了异常处理的代码):


这里的LoaderConfiguration是用来做什么的呢?它是用来解析$GROOVY_HOME/conf/groovy-starter.conf文件的,该文件内容如下(去掉了注释部分):


这表示,将$GROOVY_HOME/lib/*.jar、$HOME/.groovy/lib/*.jar以及tools.jar加入到RootLoader的classpath中,可以看出,这里包含了Groovy依赖的第三方jar包。


接下来,我们来看一下GroovyMain的源代码。GroovyMain的main函数进去之后,最终会到达processOnce方法:


可以看到,GroovyMain是通过GroovyShell来执行脚本文件的,GroovyShell的具体执行脚本的代码我们不再分析,我们只看GroovyShell的构造函数中初始化ClassLoader的代码:


由此可见,GroovyShell使用了GroovyClassLoader来加载类,而该GroovyClassLoader的parent即为GroovyShell的ClassLoader,也就是GroovyMain的ClassLoader,也就是RootLoader。


最后来总结一下Groovy脚本的启动流程(括号中表示使用的ClassLoader):


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇STL栈与队列的操作 下一篇编程算法 - 组合数 代码(C)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: