private void processOnce() throws CompilationFailedException, IOException {
GroovyShell groovy = new GroovyShell(conf);
if (isScriptFile) {
if (isScriptUrl(script)) {
groovy.run(getText(script), script.substring(script.lastIndexOf("/") + 1), args);
} else {
groovy.run(huntForTheScriptFile(script), args); // 本地脚本文件执行这行
}
} else {
groovy.run(script, "script_from_command_line", args);
}
}
可以看到,GroovyMain是通过GroovyShell来执行脚本文件的,GroovyShell的具体执行脚本的代码我们不再分析,我们只看GroovyShell的构造函数中初始化ClassLoader的代码:
final ClassLoader parentLoader = (parent!=null)?parent:GroovyShell.class.getClassLoader();
this.loader = AccessController.doPrivileged(new PrivilegedAction<GroovyClassLoader>() {
public GroovyClassLoader run() {
return new GroovyClassLoader(parentLoader,config);
}
});
由此可见,GroovyShell使用了GroovyClassLoader来加载类,而该GroovyClassLoader的parent即为GroovyShell的ClassLoader,也就是GroovyMain的ClassLoader,也就是RootLoader。
最后来总结一下Groovy脚本的启动流程(括号中表示使用的ClassLoader):
GroovyStarter
↓ (RootLoader)
GroovyMain
↓
GroovyShell
↓ (GroovyClassLoader)