我有一个带有依赖项的类,我想热部署而不重新启动依赖项。该类有一个接口,但只有一个具体的实现。
最初,我创建了一个导出接口的捆绑包,并使用未导出的激活器和实现类注册了实现。但是,如果我更新捆绑包,则在调用PackageAdmin#refreshPackages时更新后会重新启动使用已注册服务的捆绑包(这在使用fileinstall时是自动的)。
我已经通过创建一个单独的api包来解决这个问题。
这是实现这一目标的最佳方法吗?
你有没有一个捆绑导出它的api并包含在同一个捆绑中的实现。据我所知,任何给出的bundle都会导出它的所有类或没有类。我错过了什么?
答案 0 :(得分:20)
将API捆绑包与OSGi中的实现分开绝对是一种最佳做法。如果这样做,那么使用API的任何bundle只需要从API包中导入类,这可以允许您在运行时更改实现而无需重新启动依赖包。
理想情况下,您的实现包将在API提供的接口上实现接口并将实现导出为服务。这允许客户端捆绑包在不引用实现包的情况下使用该服务。
答案 1 :(得分:9)
在Apache Sling中,我们同时执行这两项操作:主要API都在自己的捆绑包中,但对于较小的内容(如扩展或可选组件),我们通常会在与API相同的捆绑包中提供默认实现。
在后一种情况下,您仍然可以允许这些默认服务可替换,例如,当您要覆盖它们时使用服务排名值。
bundle不必导出它的所有类,我们的包含默认服务的bundle只导出API包(显然默认实现在不同的包中)。
答案 2 :(得分:0)
除非有硬性要求能够在运行时替换实现,而不重新启动客户端捆绑包,否则我个人主张保持API与实现之间的显式依赖关系(通过在API包中包含impl类,或者通过来自impl。捆绑包的API包导入实现包。)
上面提到的模式的pb是它们打破了依赖链。依赖管理的好处远远超出简单的API兼容性,它们还包括确保可预测的,一致的运行时行为,以及与部署生态系统的兼容性,以及所有这些都需要管理实现依赖性。