如何使用 GroovyClassLoader 加载 GroovyCompiled 类 或如何在 loadClass 情况下设置委托

How to use GroovyClassLoader to load GroovyCompiled classes or how to set delegate in case of loadClass

我正在尝试加载在构建期间编译并作为 .class 文件放置在 classpath 中的类。为此,我尝试了

GroovyClassLoader gos = new GroovyClassLoader();

gos.loadClass("className");

这将在 java 代码中成功加载 class 文件,但它使用 AppClassLoader 加载此文件而不是 GroovyClassLoader。

我了解 GroovyClassLoader 在内部使用 AppClassLoader 找到它。 但还是有区别的:

因为 gos.parseClass(string) 会给我们一个从 GroovyClassLoader 解析的 class。

在第二种情况下实例化 class 文件时 (parseClass) 给我们委托来设置委托,但在第一种情况下 (loadClass),我们没有任何委托。

如何在执行 loadClass 后设置委托或以任何方式通过 GroovyClassLoader 加载 class 文件。

Load Class

Groovy 编译器编译 groovy 文件(HelloWorld.dsl)并将它们放在 class 路径中创建 .class 文件(HelloWorld.class ) 同名。 默认情况下编译的 class 文件(打开字节码)有 class(HelloWorld) 与 class 文件同名。

此 class 将从脚本得到扩展。现在,如果您尝试加载此 class 文件,请使用 gos.loadClass("HelloWorld").newInstance() ,它会给我们一个 Script 对象,我们将无法将委托设置为 Script 对象。它也不会被转换成 DelegatingScript。

要使您的编译 class 从 DelegatingScript 扩展,请将其添加到您的 dsl 文件 @groovy.transform.BaseScript DelegatingScript delegatingScript 顶部。 Groovy 编译器会理解这一点,并使 class 文件从 DelegatingScript 而不是之前的 Script 得到扩展。

现在,当您尝试使用 gos.loadClass("HelloWorld").newInstance() 加载 class 时,它会给出一个 DelegatingScript 对象,而不是一个 Script 对象。对于这个对象,我们可以设置委托和 运行 脚本。

要在使用 parseClass 时使用委托,我们需要将 ScriptBaseClass 设置为 DelegatingScript 到 compilerConfiguration。现在如果你尝试 gos.parseClass(dslText).newInstance() ,它会直接给出一个 DelegatingScript 对象,我们可以设置一个委托和 运行 脚本。