Groovy的ClassLoader体系

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

Groovy入门教程

注:以下分析的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:

Bootstrap ClassLoader  

         ↑  

Extension ClassLoader  

         ↑  

System ClassLoader  

         ↑  

User Custom ClassLoader  // 不一定有 

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

Groovy的ClassLoader

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

def cl = this.class.classLoader  

while (cl) {  

    println cl  

    cl = cl.parent  

输出如下: 

groovy.lang.GroovyClassLoader$InnerLoader@18622f3  

groovy.lang.GroovyClassLoader@147c1db  

org.codehaus.groovy.tools.RootLoader@186db54  

sun.misc.Launcher$AppClassLoader@192d342  

sun.misc.Launcher$ExtClassLoader@6b97fd 

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

            null                      // 即Bootstrap ClassLoader  

             ↑  

sun.misc.Launcher.ExtClassLoader      // 即Extension ClassLoader  

             ↑  

sun.misc.Launcher.AppClassLoader      // 即System ClassLoader  

             ↑  

org.codehaus.groovy.tools.RootLoader  // 以下为User Custom ClassLoader  

             ↑  

groovy.lang.GroovyClassLoader  

             ↑  

groovy.lang.GroovyClassLoader.InnerLoader 

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

Groovy脚本启动过程

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

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

#…   

startGroovy groovy.ui.GroovyMain "$@" 

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

#…  

STARTER_CLASSPATH="$GROOVY_HOME/lib/groovy-2.1.3.jar" 

#…  

startGroovy ( ) {  

    CLASS=$1 

    shift  

    # Start the Profiler or the JVM  

    if $useprofiler ; then  

        runProfiler  

    else 

        exec "$JAVACMD" $JAVA_OPTS \  

            -classpath "$STARTER_CLASSPATH" \  

            -Dscript.name="$SCRIPT_PATH" \  

            -Dprogram.name="$PROGNAME" \  

            -Dgroovy.starter.conf="$GROOVY_CONF" \  

            -Dgroovy.home="$GROOVY_HOME" \  

            -Dtools.jar="$TOOLS_JAR" \  

            $STARTER_MAIN_CLASS \  

            --main $CLASS \  

            --conf "$GROOVY_CONF" \  

            --classpath "$CP" \  

            "$@" 

    fi  

}  

 

STARTER_MAIN_CLASS=org.codehaus.groovy.tools.GroovyStarter 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/e291e3c156fa90d067c9dc6fbda7c069.html