1

我有这些捆绑:

  • Comm Service提供通信服务。
  • 通信是使用Comm Service发送/接收消息的通信包。
  • Poll以多播模式发送轮询消息。

捆绑包已经饱和,我的Communication方法是为特定操作实现其他捆绑包——投票捆绑包将负责发送民意调查,明信片捆绑包用于发送明信片等(只是一些示例)。

当捆绑需要委派其发送投票/明信片/消息的工作时,是否将Comm Service服务作为输入参数传递给捆绑?PollCommunication

下面的片段是否正确?

通讯包代码

PollBundle p = new PollBundleImpl();
p.sendPoll(String pollQuestion, CommService cs);

还是让Poll/捆绑包自行Postcard检索服务的更好方法?Comm Service

4

3 回答 3

8

不得在包之间传递服务对象;如果您这样做,那么 OSGi 框架将失去对哪些捆绑包具有服务可见性的控制,因此它无法在该服务需要离开时通知全套捆绑包。

因此,轮询包必须为自己找到 CommService。有很多方法可以做到这一点。我强烈建议使用OSGi 规范中的声明式服务。与bnd 注释结合使用,您将能够编写 Poll 包的代码,如下所示:

@Component
public class Polling {

    private CommService commService;

    @Reference
    public void setCommService(CommService cs) {
        this.commService = cs;
    }

    public void someMethodThatUsesCommService() {
         sendPoll(cs);
         // ...
    }
}

我推荐这种方法而不是 Jacek Laskowski 在他的回答中描述的 Blueprint 解决方案,因为它不需要编写冗长且非类型安全的 XML 文件,并且它具有与 OSGi 服务的生命周期相匹配的更好的生命周期特征。然而,Declarative Services 和 Blueprint 方法肯定比使用低级 OSGi API(例如ServiceTracker)更安全ServiceListener

于 2013-03-08T20:04:25.793 回答
2

我强烈建议利用依赖注入来解耦捆绑包OSGi Blueprint(请参阅OSGi Service Platform Enterprise Specification中的Blueprint Container Specification,但请注意它适用于 V5 版本)。

使用规范,您可以使用单独的 xml 文件声明捆绑包的依赖关系 - OSGI-INF/blueprint/*.xml(默认设置,但可以使用Bundle-Blueprint标头更改)。

因此,在您的情况下,您将开发Comm Service其服务是该捆绑包的依赖项的Communication捆绑包。还有Poll可能Postcard注册服务的同一服务接口的捆绑包,以便它们可以成为Communication捆绑包的依赖项。

在这样的配置中,Communication传递Comm Service捆绑/服务的不是捆绑,而是在初始化期间PollPostcard捆绑获得它们的Comm Service服务依赖关系。

这是捆绑包的假设蓝图配置Poll

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
  <bean id="PollSenderBean" class="pl.japila.osgi.poll.PollSender">
    <argument ref="commService" />
  </bean>
  <service id="PollSenderBeanService" ref="PollSenderBean" 
           interface="pl.japila.osgi.Sender">
    <service-properties>
      <entry key="type" value="poll" />
    </service-properties>
  </service>
  <reference id="commService" interface="pl.japila.osgi.comm.CommService" />
</blueprint>

捆绑包将Postcard是相似的。请注意 的entry值,poll以便在需要此类查询时获得特定服务。

捆绑包的蓝图配置Communication如下:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
  <reference-list activation="lazy" member-type="service-object"
                  id="Sender" interface="pl.japila.osgi.Sender" />
</blueprint>

参考规范,也许还有Apache Aries Blueprint 模块来学习和学习解决方案。

于 2013-03-08T17:54:33.960 回答
1

除非你需要CommService在不同的调用中使用不同的p.sendPoll(String pollQuestion..)我会说,让我们自己PollBundle找到CommService

基本上这减少了耦合。您只需要知道PollBundle发送投票。这实际上取决于您的架构,但总的来说,您需要移动的对象越少,接口越简单越好。

于 2013-03-08T16:56:15.557 回答