将动态OSGi服务选择放在自己的服务中?

时间:2013-06-12 21:48:14

标签: java osgi

在我们的OSGi系统的设计中,我们有一个重复的场景,其中一个服务想要对部署的服务的子集应用一些特定的处理(“处理”)。在简单的情况下,我们会让目标服务分配一些服务属性,以表明他们需要特殊处理,然后让治疗服务找到白板风格。

但是,当用于确定哪些服务子集到目标的算法需要使用Java逻辑来实现并且不容易用bundle本身设置的静态属性来表示时,这是如何设计得最好的?

此外,如果我们有多个要重复使用相同服务定位的处理服务,理想情况下,选择算法应该在自己的服务中实现。我们称之为SelectService,并说它具有动态识别“abc”和“xyz”类别服务的逻辑。

我可以想到这些主要的替代方案,也许还有更多?

  1. SelectService检查已部署的服务,然后以某种方式(如何?)在适用时设置属性“abc”和“xyz”。然后,治疗服务可以使用带有属性过滤器的标准ServiceTracker来查找他们想要的服务。

  2. SelectService提供方法getAbcServices()getXyzServices(),它们会返回一些类似ServiceTracker的对象。治疗服务可以调用这些方法来查找目标服务。

  3. 让治疗服务在服务注册表(服务接口或服务属性)中声明某些内容,以表达对服务选择的兴趣。 SelectService然后找到这些愿望的白板样式并通知治疗服务选择。

  4. 这是在OSGi系统中思考的错误方法,您甚至不应该这样做: - )


  5. 编辑1:

    总结一下这个场景,你可以说它类似于声明服务或蓝图等扩展服务:

    targeted  <-->  extender
    service         service
    

    另外,扩展器服务被分成两部分/层,以便重用选择逻辑:

    targeted        extender         extender
    service   <-->  service    <-->  service
                    treatment   **   selection
                    logic            logic
    

    有趣的部分是治疗和选择逻辑之间的API(**),因为它提到了其他服务,还需要一些添加/删除事件机制。为了便于理解,还希望尽可能多地使用标准OSGi模式和支持函数。


    [Meta:将讨论划分为一个答案线程(答案+评论)可能会很好吗?]

2 个答案:

答案 0 :(得分:0)

如果您需要对服务进行“动态”或程序化过滤,则需要使用静态过滤器,该过滤器接收可能被选中的所有服务。最简单的过滤器是 null 过滤器,它只接受所有正确类型的服务。

例如,使用Declarative Services实现:

@Reference(multiple = true, dynamic = true, optional = true)
public void addFooService(Foo foo, Map<String, Object> serviceProps) {
    // TODO: implement logic here to read serviceProps. Return early from
    // this method if the service doesn't match your dynamic criteria.
}
public void removeFooService(Foo foo, Map<String, Object> serviceProps) {
    // Be careful here, you will get services back that you didn't care about in the
    // 'add' method.
}

现在要解决问题的第二部分......将选择逻辑本身变成一个服务是一个有趣的想法,但它会让你的生活变得复杂。我主要担心的是:如果SelectService动态变化会发生什么?我将不得不根据新的选择算法重新过滤整套服务。 之前 SelectService出现的情况......我是否看到所有服务都未经过滤?还是零服务?等

至于你最后的问题是关于你是否正走在正确的道路上......很难说不知道真正的用例。但是我认为你可能会让事情变得比他们需要的更复杂。例如,也许您不应该拥有相同类型的大量服务?也许你应该将它们分成多种类型?

作为在许多客户端中复制选择逻辑或将其拉入选择服务的替代方法,为什么不创建实现选择逻辑的单个组件,然后根据聚合集提供一些更高级别或包装功能?

答案 1 :(得分:0)

您可以查看服务代理。使用OSGi服务挂钩,您可以有选择地隐藏服务并注册代理。这种模式允许你做几乎任何事情,而这些服务的消费者仍然不知道发生了什么。

soapbox { 也就是说,总的来说,我会尽量保持简单。虽然这些“扩展”中的许多对于一些简单的工作看起来非常有用,但随着时间的推移它们往往会成为瓶颈。缺乏广泛的文档,并且通常没有随时间推移所需的功能,这使得它们成为未来开发人员的PITA。

我看到很多系统变得非常复杂,不是因为他们的域,而是因为随着时间的推移,太多开发人员添加了他们自己的中间件以试图减少他们自己的工作量,即自我造成的复杂性。有时,一些冗余更容易理解/维护。 }