【问题标题】:GroovyClassLoading MechanismGroovy 类加载机制
【发布时间】:2014-03-12 05:55:34
【问题描述】:

我真的是 groovy 脚本的新手,但是按照一些教程,我尝试使用 GroovyClassLoaderparseClass() 方法在我的 java 代码中动态加载一些 groovy 类。 我写了一些sn-p,对我来说效果很好。问题是我不清楚 groovy 引擎在我的视野之外做什么以及这些脚本是如何编译的?
是否创建了一个新类并将其加载到 jvm 中?还是我的应用程序使用了一些缓存的源?

这是我要解析的类:

  private static class MyScript {

  @Override
  public String toString()
  {
     StringBuilder builder = new StringBuilder();
     builder.append("public class SomeClass\n");
     builder.append("{\n");
     builder.append("Some code...").append("\n");
     builder.append("}\n");
     return builder.toString();
  }

我用build() 加载它如下:

private Class MyGroovyBuilder {
  private Script script = new Script();
  public String build() throws TemplateCompilationException
  //
  String groovyText = script.toString();
  //
  CompilerConfiguration config = new CompilerConfiguration();
  //
  byte[] bytes;
  try
  {
     bytes = groovyText.getBytes(config.getSourceEncoding());
  }
  catch (UnsupportedEncodingException e)
  {
     throw new TemplateCompilationException(e, groovyText);
  }
  //
  InputStream in = new ByteArrayInputStream(bytes);
  GroovyCodeSource gcs = new GroovyCodeSource(in, "SomeName", "/groovy/shell");
  GroovyClassLoader loader = new
  GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config);
  Class<?> scriptClass;
  try
  {
     scriptClass = loader.parseClass(gcs, false);
  }
  catch (CompilationFailedException e)
  {
     throw new GroovyCompilationException(e, "SomeName", groovyText);
  }
  catch (ClassFormatError e)
  {
     throw new GroovyCompilationException(e, "SomeName", groovyText);
  }
return scriptClass.getName();

}


非常感谢任何澄清。

BR。

【问题讨论】:

    标签: java groovy classloader groovyclassloader


    【解决方案1】:

    加载类后,它会出现在您的类加载器中,并且可以像访问任何其他类一样访问。

    有一个简单的教程 [here],展示了如何从字符串加载类。

    在最简单的情况下,您可以加载类,并持有它的 Class 对象,使用它来动态创建对象。对于字段访问或方法调用,您可以依赖 Groovy 的动态特性。

    在幕后没有“缓存源”或类似的东西,你可以忘记你的类是从哪里加载的。您还可以缓存已经编译的类,并将它们保存在某处,如 [here] 所述。如果您需要经常加载相同的类,它将大大提高性能。

    但是,深入研究主题会更好,因为动态类加载是高级 Java/Groovy 技术,它是链式类加载器的整个基础架构,因此最好参考有关它们的文档。

    下面的链接可能会有所帮助。

    http://javarevisited.blogspot.ru/2012/12/how-classloader-works-in-java.html

    How to use URLClassLoader to load a *.class file?

    【讨论】:

    • 嗨@Seaagull,感谢您的解释,但让我们更深入一点,假设我正在配置一些具有两个节点的集群环境,并且我在 node1中创建了该对象的一个​​实例> 然后想将其复制到 node2;复制过程肯定会失败,因为第二个节点不包含此类的源,不是吗?这种情况应该如何处理?
    • @tmarwen 好的,让我们更深入一点 ;) 你有几个独立的虚拟机,所以你必须在每个虚拟机上共享加载的类。对于复制,您可以序列化您的类实例,将其传输到第二个节点,然后在那里反序列化。
    • 所以这应该是手动完成的,这意味着它要回到我身上来实现一些共享资源机制。没有开箱即用的功能可以简化这些类的复制吗?
    • @tmarwen 据我所知,在 Groovy 中 - 没有。有几种集群化解决方案。我听说过 Terracota,一种在多台计算机上分配 RAM 的方法。查看stackoverflow.com/questions/383920/… 了解更多信息。
    • 非常感谢您帮助过半条马路。现在不可能考虑 Terracotta,因为已经使用了缓存框架jbosscache,但会放入一些迁移/组合模式,TY。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 2019-08-24
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多