GroovyClassLoader
groovy 类加载器,可以加载 groovy 类构造器接收三个参数:
1. 父加载器
2. 编译配置项
3. 是否添加配置类路径
主要的三个功能:
defineClass:定义类
loadClass:加载类
parseClass:解析类
解析类的主要方法:parseClass 将 GroovyCodeSource 解析成 java 类,如果已经存在,则从缓存里获取,不再重新解析
实际解析入口方法-doParseClass
(1)根据编译配置项和 codesource 创建编译单元(CompilationUnit)
(2)创建 source 单元(SourceUnit)
(3)通过类收集器(ClassCollector)连接 CompilationUnit 和 SourceUnit
(4)执行 compile 方法,从类收集器中获取结果(generatedClass)
类缓存
groovy 会将已解析的类缓存到内存里,具体缓存 Key 标识生成过程如下:
private String genSourceCacheKey(GroovyCodeSource codeSource) {
StringBuilder strToDigest;
String scriptText = codeSource.getScriptText();
if (null != scriptText) {
strToDigest = new StringBuilder((int) (scriptText.length() * 1.2));
strToDigest.append("scriptText:").append(scriptText);
CodeSource cs = codeSource.getCodeSource();
if (null != cs) {
strToDigest.append("/codeSource:").append(cs);
}
} else {
strToDigest = new StringBuilder(32);
// if the script text is null, i.e. the script content is invalid
// use the name as cache key for the time being to trigger the validation by `groovy.lang.GroovyClassLoader.validate`
// note: the script will not be cached due to the invalid script content,
// so it does not matter even if cache key is not the md5 value of script content
strToDigest.append("name:").append(codeSource.getName());
}
try {
return EncodingGroovyMethods.md5(strToDigest);
} catch (NoSuchAlgorithmException e) {
throw new GroovyRuntimeException(e); // should never reach here!
}
}
复制代码
评论