【问题标题】:Why is it a bad idea to manually wire OSGi services?为什么手动连接 OSGi 服务是个坏主意?
【发布时间】:2017-11-16 09:54:27
【问题描述】:

为了优先考虑某些服务实现,我编写了java.util.ServiceLoader 的可定制版本(通过非 OSGi 代码的首选项文件为实现添加优先级和启用/禁用标志)。

客户很高兴并希望对 OSGi 服务实现进行同样的定制。 设计的解决方案基于在BundleContext 上调用getServiceReferences(Class<S> clazz, String filter) 并使用null 过滤器来检索所有实现。

尽管如此,在如此低的级别上摆弄 OSGi 会留下不好的味道。有很多样板代码(例如 BundleActivator 的强制子类型),并且使用的方法也会阻碍对声明式服务和某些时间点的平滑升级。

我也阅读了SERVICE_RANKING 属性,但与上述方法中的首选项文件相比,它的缺点是每个实现都设置了自己的排名属性,之后无法更改排名。


所以我的问题是:反对这种低级方法的好论据是什么?为什么要使用声明式服务?

【问题讨论】:

  • 考虑将SERVICE_RANKING与排名策略一起使用,例如标准代码排名 1000。这可行吗?

标签: java osgi apache-felix declarative-services


【解决方案1】:

OSGi 的核心是一个动态环境。捆绑包和服务可以随时来来去去(理论上)。因此,应对这种环境的唯一方法是对变化做出反应,而不是等待某事发生。

例如,一个声明式服务组件会在其所有强制服务出现后出现,而如果其中一个消失则消失。 基于服务加载器或类似的解决方案将主动获取可用的服务,如果此类服务是强制性的,那么您将不得不阻止它直到它可用。这很容易导致应用程序死锁。

当然,在实践中,应用程序通常不是那么动态的。在大多数情况下,这只影响应用程序的启动。所以在很多情况下,阻塞行为可以起作用,但它会产生一个本质上很脆弱的应用程序。

另一方面,如果您的应用程序需要在 OSGi 内部和外部运行,那么 DS 就有问题,因为它依赖于 OSGi 的存在。 典型的例子是 Aapache CXF 和 Apache Camel。两者都不使用 DS,而是为 OSGi 中的使用发明了不同的抽象,并且有时正是因为这个原因,两者都在 OSGi 中出现了问题。仍然很难改进这一点,因为他们也需要在 OSGi 之外工作。

【讨论】:

  • 所以主要论点是易于部署(包括捆绑包的“热交换”)?
  • 争论是像 DS 这样的反应式方法可以为您提供稳定的系统行为。当系统达到一定的复杂性(例如死锁或超时)时,带有阻塞的手动连接往往会使您的系统启动中断。
  • 好的,你会如何偏爱某些服务实现而不是其他实现,例如客户特定的实现比通用代码更受青睐?有没有通过配置文件工作的解决方案?可能不需要重新编译?
  • 在 DS 上,您可以使用 service.ranking 属性自动选择服务。但是切换到新服务只适用于贪婪的引用。另一种可能性是在 DS 客户端组件的配置中使用 myRef.target。它允许使用 ldap 过滤器语法指定要选择的服务。
猜你喜欢
  • 2015-01-05
  • 2014-06-04
  • 2017-01-16
  • 1970-01-01
  • 1970-01-01
  • 2017-01-31
  • 1970-01-01
  • 1970-01-01
  • 2011-11-29
相关资源
最近更新 更多