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

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


该配置允许用户在运行时指定要使用的fizzClass(对于什么东西,实际上并不重要)。问题是,我希望这个应用程序接受插件;也就是说,我可以(在运行时动态地)将JAR添加到应用中,也许在其中可以打包其他Fizz实现,然后用户可以在其配置文件中指定这些新可用的impls。例如,也许我的应用程序中仅包含public class FizzImpl implements Fizz。现在,假设有人开发了一个包含foo-plugin.jar的插件public class FooFizz implements 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运行时的理解!

假设我对我的理解或多或少是正确的,我的问题是:为了为我的应用程序开发插件,我是否遵循包装捆绑包的常规说明,或者是否有特殊的“技巧”来利用Felix的插件体系结构?

最佳答案

在OSGi中实现插件体系结构的一个好方法是使用OSGi服务。您将Fizz接口和其他所有构成API的东西打包在一起。然后将第二个捆绑软件用于FizzImpl并使用激活器或将impl实例发布为OSGi服务的蓝图。
最后一部分是您的主应用程序,它需要绑定服务并使用该接口调用服务。
因此,这将是您的默认设置。

然后,某人可以创建具有替代实现的另一个捆绑软件,并将其作为服务发布。为了区分这两个服务,可以在发布服务时指定属性。

然后,在主应用程序中,您可以使用可配置的筛选器来绑定与筛选器匹配的服务。因此,您可以通过更改过滤器来切换显示。

我在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

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

07-24 18:36
查看更多