java - OSGi解决可插拔架构

标签 java osgi apache-felix modularity

我有一个 Java 应用程序(应部署为可执行 JAR),它采用 JSON 文件作为输入,如下所示:

"appConfig": {
    "fizzClass": "com.me.myorg.FizzImpl"
    // Lots of other configs
}

该配置允许用户指定在运行时使用什么fizzClass(对于某物,具体是什么并不重要)。问题是,我希望这个应用程序接受插件;也就是说,我可以(在运行时动态地)将 JAR 添加到应用程序,其中可能会打包其他 Fizz 实现,然后用户可以在其配置文件中指定这些新可用的 impl。例如,也许我的应用程序中只有 public class FizzImpl Implements Fizz 。现在假设有人开发了一个插件,foo-plugin.jar,其中包含公共(public)类 FooFizz 实现了 Fizz。现在,在作为插件部署到我的应用程序后,最终用户可以向应用程序传递以下配置:

"appConfig": {
    "fizzClass": "com.some.other.foo.FooFizz"
    // Lots of other configs
}

...没有得到 ClassNotFoundException 等。因为现在 FooFizz 位于应用程序的运行时类路径上。

OSGi 感觉是这个问题的完美解决方案。我正在尝试了解 Apache Felix 的架构。我的理解是,我将应用程序部署为 JAR,但包含 Felix JAR 作为其依赖项,这使我可以访问插件架构。然后我必须要求插件开发人员将他们的 JAR 打包为 OSGi 包。因此,首先,如果这些陈述有任何误导或不正确的地方,请首先纠正我对 Java JAR 如何利用 Felix OSGi 运行时的理解!

假设我的理解或多或少是正确的,我的问题是:为了为我的应用程序开发插件,我是否只遵循打包 bundle 的正常说明,或者是否有特殊的“技巧”利用 Felix 的插件架构?

最佳答案

在 OSGi 中实现插件架构的一个好方法是使用 OSGi 服务。您可以将 Fizz 接口(interface)以及构成 API 的所有其他内容打包到一个包中。然后,您为 FizzImpl 使用第二个包并使用激活器或例如将 impl 实例发布为 OSGi 服务的蓝图。 最后一部分是您的主应用程序,它需要绑定(bind)服务并使用接口(interface)调用服务。 所以这将是您的默认设置。

然后有人可以使用替代实现创建另一个 bundle ,并将其发布为服务。为了区分这两种服务,您可以在发布服务时指定属性。

然后在您的主应用程序中,您可以使用可配置的过滤器来绑定(bind)与过滤器匹配的服务。所以你可以通过改变过滤器来切换impl。

我在 cxf xkms 中使用了这种方法来为 xkms 实现一个基于 ldap 的后端,该后端可以切换为其他内容。 这是 ldap impl 的蓝图文件: https://github.com/apache/cxf/blob/master/services/xkms/xkms-x509-repo-ldap/src/main/resources/OSGI-INF/blueprint/blueprint.xml

这是主应用程序的蓝图 xml: https://github.com/apache/cxf/blob/master/services/xkms/xkms-osgi/src/main/resources/OSGI-INF/blueprint/blueprint.xml

最后一部分是使用配置过滤器绑定(bind)服务的 java 代码: https://github.com/apache/cxf/blob/master/services/xkms/xkms-service/src/main/java/org/apache/cxf/xkms/service/CertificateRepoProxyFactory.java

关于java - OSGi解决可插拔架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24436921/

相关文章:

java - 在 2.23.0 版本中,如果没有 CamelContext,则无法创建 Camel DefaultMessage

java - felix scr 中 @Reference 和 @References 注解之间的区别

java - 如何部署 OSGi 应用程序和依赖项?

java - OSGi JAR 一旦运行,是否可以要求其容器从另一个位置加载另一个 OSGi JAR?

java - 无法将包含 '&' 或 ';' 的 XML 字符串转换为 JSON 对象

Java正则表达式性能

java - jsp txt 文件下载给我 jsp 内容

java - OSGI SCR 框架中的可选依赖项

java - OSGi 组件可通过 Apache Felix 配置

java - 从给定索引处将 ArrayList 添加到另一个 ArrayList