【问题标题】:How to create a pluginable Java program?如何创建可插入的 Java 程序?
【发布时间】:2010-09-06 17:29:58
【问题描述】:

我想创建一个可以用插件扩展的 Java 程序。我该怎么做?我应该在哪里寻找?

我有一组插件必须实现的接口,它应该在一个 jar 中。程序应该在相对(程序)文件夹中监视新的 jar,并以某种方式注册它们。


虽然我确实喜欢 Eclipse RCP,但我认为它对于我的简单需求来说太过分了。

Spring 也是一样,不过反正我也要去看看,还是试试看吧。

但是,我还是希望找到一种方法来尽可能简单地创建我自己的插件“框架”。

【问题讨论】:

标签: java plugins plugin-architecture


【解决方案1】:

查看OSGi

一方面,OSGi 提供了各种基础架构,用于管理、启动和使用模块化软件组件执行许多其他操作。另一方面,它可能对您的需求来说太重了。

顺便说一下,Eclipse 使用 OSGi 来管理它的插件。

【讨论】:

  • +1 用于 OSGi。我发现它在简单的 ClassLoader 技巧(这将给你留下很多需要重新发明的轮子)和 Eclipse RCP(不那么复杂的任务的大框架)之间找到合适的大小。
【解决方案2】:

在本土的类加载器方法中: 虽然它绝对是了解类加载器的好方法,但有一种叫做“类加载器地狱”的东西,大多数人都知道在大型项目中使用它时与之搏斗的人。冲突类很容易引入但很难解决。

Eclipse 几年前转向 OSGi 是有充分理由的。 因此,如果它不仅仅是一个宠物项目,请认真研究 OSGi。它值得一看。 您将了解类加载器以及新兴的技术标准。

【讨论】:

  • osgi 很不错,但对于在启动时加载然后未触及的小型插件来说,它太大而复杂
【解决方案3】:

我已经为我过去编写的软件做过这个,它非常方便。我首先创建了一个我所有的“插件”类都需要实现的接口。然后我使用 Java ClassLoader 加载这些类并创建它们的实例。

您可以这样做的一种方法是:

File dir = new File("put path to classes you want to load here");
URL loadPath = dir.toURI().toURL();
URL[] classUrl = new URL[]{loadPath};

ClassLoader cl = new URLClassLoader(classUrl);

Class loadedClass = cl.loadClass("classname"); // must be in package.class name format

已经加载了类,现在你需要创建它的一个实例,假设接口名称是 MyModule:

MyModule modInstance = (MyModule)loadedClass.newInstance();

【讨论】:

  • 我知道我在这个线程上有点晚了,但是如果你想遍历目录中的所有给定类并加载它们怎么办?有没有什么地方可以在线看到有效的实现和代码?除此之外,我了解你们中的大多数代码并且非常简单,谢谢! +1
  • @CodyRichardson 在knowbase.org/viewtopic.php?id=31 有一个简单实现的完整示例;它使用 Java 8 和 Gradle 4。
  • @Alexiy 感谢该链接,它帮助很大,基本上是我需要的一切。一开始有点复杂(主要是 lambdas),但这只是因为我是一个 java 菜鸟 :) 我看了几遍,感觉更有意义了。谢谢!
  • 我上面的链接已经不存在了,教程现在托管在这里 - alexiyorlov.github.io/tutorials/java-plugins.html
  • 我尝试了这个变体等等。但是会发生这种情况:我无法将我的类转换为接口,因为这会引发 ClassCastException。 Java 1.8 或更高版本有问题吗?
【解决方案4】:

我建议您仔细查看the Java Service Provider (SPI) API。它提供了一个简单的系统,用于查找类路径上所有 Jars 中的所有类,这些类公开为实现特定服务。我过去曾将它用于插件系统并取得了巨大成功。

【讨论】:

  • 请注意,sun.misc.Service 类已被 java.util.ServiceLoader 类取代。
【解决方案5】:

虽然我会支持接受的解决方案,但如果需要基本的插件支持(大多数时候都是这种情况),还有Java Plugin Framework (JPF),虽然缺乏适当的文档,但它是一个非常整洁的插件框架实现。

它很容易部署,并且 - 当您通过类加载特性时 - 非常容易开发。上面的注释是要注意插件目录下的插件加载路径必须以 full 类路径命名,除了将其类文件部署在名为 path 的普通包路径中。例如

plugins
`-com.my.package.plugins
  `-com
    `-my
      `-package
        `-plugins
          |- Class1.class
          `- Class2.class

【讨论】:

    【解决方案6】:

    您是否考虑过在 Eclipse 的富客户端平台之上构建,然后公开 Eclipse 扩展框架?

    此外,根据您的需要,Spring 框架可能会帮助您完成这些以及您可能想做的其他事情:http://www.springframework.org/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 2010-10-27
      • 1970-01-01
      • 1970-01-01
      • 2012-06-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多