Java中处理插件的好模式有哪些?

3
This question is somewhat inspired by a previous question I've asked.
Most of the code I write has to do with an API, which by its nature has to be easily extendible. A common problem that I and the rest of my team wrestle with is how to handle plugins, i.e classes that may extend our own interfaces and in the final implementation should feel like an atomic part of the solution. I'm thinking in particular of the following kind of use case (to use a car analogy). Interface:
Car

提供的实现:
Ford
Audi

第三方实现:
Toyota

我们通常要求类 CarDealer 意识到所有现有的 Car 实现,而不需要第三方强制在配置文件中明确声明 Car。 我一直在考虑的一个想法是让 Car 的实现自己向 CarDealer 注册,但这会引起新的问题,因为在显式引用之前,Toyota(或任何其他实现)不会被初始化,这是个进退两难。 对实现 Car 进行注释,然后通过代码并初始化具有相关注释的任何类也是一种方法,但我担心这可能会非常重资源消耗。

我认为我们不可能是第一个遇到这个问题的人,那么有没有已知的设计模式来解决这个问题呢?


请参见 http://stackoverflow.com/questions/7587318 - Mot
4个回答

3

请看java.util.ServiceLoader。基本上,您需要创建一个接口,然后所有服务的实现者都可以在其jar中包含一个文件/META-INF/services/<fully-qualified-name-of-interface>列出所有实现。

ServiceLoader可以用于加载类路径中发现的所有实现(例如,JDBC 4.0也要求驱动程序使用此功能来摆脱使用Class.forName(...)来加载驱动程序)。


0

你可以为第三方类指定一个位置,然后使用反射来实例化它们。

或者编写一个自定义的类加载器。


使用固定位置可能是我们最终会得到的结果,但它比我想要的更笨拙。您能详细说明一下自定义类加载器的工作原理吗? - mikek

0

谈到这种情况,我想到了两件事:

  1. 在您的抽象实现(或接口)中声明一个名为getName()的方法,在这种情况下,Toyota将返回“Toyota”,等等。然后,您可以考虑扫描整个类路径并收集Car的子类(使用此方法)。最后,使用(静态?)工厂方法获取所有“Car实现”或按名称选择它们。使用反射获取新对象。

  2. 有一个名为OSGi的平台,专门用于处理插件(通过使用OSGi服务)。当使用Spring DM与OSGi通信时,使用起来非常容易。有两个主要实现:Felix和Equinox。

总之:如果您可以选择平台,请选择OSGi。如果不能,则必须扫描类路径。


0

听起来你正在寻找依赖注入。(奖励:维基百科使用了汽车的例子)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接