13

我是 OSGI 的初学者,我想知道是否有人可以告诉我创建 OSGI 服务与单例模式之间的区别。例如,假设我有一个core提供的包IService,以及需要访问它的多个包。我可以:

  1. 在 -bundle 中注册一个服务,core插件可以在其中访问
  2. 提供一个单例类,它提供服务

使用 OSGI 服务似乎相当繁琐;并且由于插件无论如何都必须依赖Core(获取接口),使用OSGI服务有什么好处?

4

4 回答 4

16

服务是独立模块之间的连接。让模块依赖于服务(及其规范包)可以显着减少模块之间的耦合,从而提供模块化的许多好处。

我认为单例模式有两种不同的使用方式:您只想在一组用户之间共享一个对象(例如日志服务),或者您实际上只能拥有一个实例(例如只有一个硬件)。总的来说,我看到企业软件界的大多数人都在谈论前者。然而,经验表明,随着项目的增长,单例变得不那么单例,而是更多地成为共享对象,或者至少看起来是共享对象。OSGi 的好处是您可以对两者进行建模,并且“单例”的客户端不会注意到它,也不需要一些中央配置。原因是 OSGi 依赖于负责的模块,注册服务是本地决定,就像监听服务一样。

服务的力量不在于它的动态(尽管它们很酷,尤其是在开发过程中),服务的本质是它们在模块内部提供完全的本地控制,而无需中央配置。一旦您了解了它的强大功能,就没有回头路了:-)

最后,OSGi 服务并不麻烦,因为我们有带注释的 DS。注册服务现在比创建 Spring bean 简单得多,没有 xml,没有中央配置:


// A component registered as a ISingleton service
@Component
public class MyImpl implements ISingleton {
  void doSingle() { ... }
}

// A component that uses the ISingleton component
@Component
public class MyConsumer {

  @Reference
  void setISingleton(ISingleton is) { ... }
}

...动态很大程度上是免费的...

于 2012-09-28T06:34:40.003 回答
7

简短的回答:如果你不需要——也不会——需要 OSGi 服务的好处(例如,动态管理的服务实现和服务搜索),那么你就不需要 OSGi 服务。

但除了服务是否繁琐之外,这里还有更多需要考虑的因素。哎呀,OSGi本身可以被认为是麻烦的。另一个捆绑包是否需要提供该类的实现?也许不吧。核心捆绑包是否会关闭或无法按需提供实现?也许。

要确定某项服务是否适合所讨论的课程,请阅读 OSGi 联盟的 What Is OSGi 页面上的一项服务的具体好处的概要。他们很好地解释了你的单例类如何变得比服务更麻烦。

祝你好运。

于 2012-09-27T17:51:32.927 回答
2

我的OSGi Threading Model的 poc 导致我相信,每个服务对于服务使用者来说都是一个单例。作为唯一一个服务对象被注册到 osgi 服务注册表中。(但您也可以覆盖此行为)。因此,就编程而言,单例类和 OSGi 服务的行为是相同的。您的类级别变量在各种服务使用者调用之间共享。

我会说 OSGI 服务是 Singleton++

但也有区别。OSGi 为每个服务提供了一个单独的类加载器,这在单例中是不可能的。所有 {singleton} 类都由单个类加载器加载。我们不能在一个单例中拥有两个具有相同名称(完全限定名称)的类,但这在 OSGi 中是可能的。

在某些情况下,我们必须确认一个类应该只加载一次(使休眠会话工厂、hdfc 服务初始化、POJO 创建这些是重初始化只需要一次)。现在,如果您生活在 Java EE 场景中,有时您的单例类会被两个不同的类加载器加载两次。所以这导致执行静态块的两倍;一份不必要的工作。OSGi 可以轻松处理此类类加载器问题(因为您是初学者,我觉得类加载本身在接下来的几天对您来说是个问题)。

OSGi 提供的另一个很棒的特性是更新包。考虑您更改了单例类中的代码。现在您需要在正在运行的应用程序中部署这个更新的类。您基本上需要重新启动系统,以便每个单例类加载器更新单例的新实例。这在 OSGi 中不是必需的,只需更新捆绑包。

我会说,如果您要为更大的应用程序(企业规模)设计,或者如果您需要为有限的硬件容量(低内存限制,低计算能力)设计代码,那么选择 OSGi,它最适合极端结束。对于所有其他人,您的普通 java 编码将完美运行。

于 2012-09-28T05:29:52.307 回答
1

您可以管理服务的生命周期(部署新版本的服务,同时运行多个版本等),但如果不重新启动 JVM,则无法管理单例的生命周期(即使重新启动,您也只能在任何时间点)。

于 2012-09-27T17:42:54.590 回答