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! }}
复制代码
评论