【问题标题】:OSGI Service components With same interface具有相同接口的 OSGI 服务组件
【发布时间】:2015-01-25 19:52:27
【问题描述】:

我需要创建具有相同接口的服务组件。这意味着我对相同的接口有不同的实现。我试图创建两个具有相同界面的组件,其中一个仅处于活动状态。

我正在使用Equinox 声明式。你有更好的设计来解决这个问题吗?请在下面找到我的配置。

Component1.xml

 <?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="comp1">
   <implementation class="com.demo.impl.CompOneImpl"/>
   <service>
      <provide interface="com.demo.IComponent"/>
   </service>
 </scr:component>

Component2.xml

    <?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="comp2">
   <implementation class="com.demo.impl.CompTwoImpl"/>
   <service>
      <provide interface="com.demo.IComponent"/>
   </service>
 </scr:component>

从消费者那里访问组件

消费组件

comp1.xml

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="consumeComp1">
   <implementation class="com.demo.service.ConsumeCompOne"/>
   <reference bind="setComp" cardinality="1..1" interface="com.demo.IComponent" name="comp1" policy="static" unbind="unsetComp"/>
</scr:component>

comp2.xml

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="consumeComp2">
   <implementation class="com.demo.service.ConsumeCompTwo"/>
   <reference bind="setComp" cardinality="1..1" interface="com.demo.IComponent" name="comp2" policy="static" unbind="unsetComp"/>
</scr:component>

当我尝试通过 ConsumeCompOne 和 ConsumeCompTwo 类分别访问 comp1 和 comp2 时,我总是得到相同的组件,无论是 comp1 还是 comp2。请帮我解决这个问题。

提前谢谢你

哥们

【问题讨论】:

    标签: osgi equinox declarative-services


    【解决方案1】:

    DS 工作正常,所以这里没有什么需要解决的。

    正如您所说,两个消费者组件都获得了IComponent 服务的实例,这正是它们作为引用请求的内容。

    【讨论】:

    • 什么意思?那么我的实现应该可以正常工作吗?我创建了 ConsumeCompOne 实例并进行访问,但它有时会返回错误。
    • 你说它被提供了一个组件的实例。那为什么错了呢?
    • 我打印了两个消费者适配器,它正在打印相同的实现类,例如 com.demo.impl.CompOneImpl@14e98c44 和 com.demo.impl.CompOneImpl@14e98c44 ,我想知道两个实例如何指向相同的实现?我在配置上做错了吗?
    • 是的,但是为什么他们都指向同一个实现是错误的呢?他们是服务的消费者,为什么他们关心提供了哪个实现?如果消费者依赖于特定的实现类,那么它们就不再是解耦的,使用服务也没有意义。
    【解决方案2】:

    如果您希望能够选择服务的特定实例,请使用属性发布它以识别它。然后,在客户端上,您可以使用 OSGi 服务过滤器来选择匹配的服务,例如特殊的键/值组合。

    【讨论】:

    • 您是否有任何带有声明性的示例代码可以通过属性访问?会更有帮助
    【解决方案3】:

    您想使用reference 元素上的target 属性来选择要绑定的特定服务。

    comp1.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="consumeComp1">
       <implementation class="com.demo.service.ConsumeCompOne"/>
       <reference bind="setComp" cardinality="1..1" interface="com.demo.IComponent" name="comp1" policy="static" unbind="unsetComp"
         target="(component.name=comp1)"/>
    </scr:component>
    

    comp2.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="consumeComp2">
       <implementation class="com.demo.service.ConsumeCompTwo"/>
       <reference bind="setComp" cardinality="1..1" interface="com.demo.IComponent" name="comp2" policy="static" unbind="unsetComp"
         target="(component.name=comp2)"/>
    </scr:component>
    

    【讨论】:

    • 哇。这工作正常。非常感谢你们的支持。你们救了我;)很高兴
    • BJ,我担心提问者在这里没有学到很多关于通过服务解耦的好处......这就是我在回答中提出问题的原因。哦,好吧。
    猜你喜欢
    • 1970-01-01
    • 2010-12-28
    • 2013-10-18
    • 1970-01-01
    • 2013-10-31
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 2011-02-09
    相关资源
    最近更新 更多