1

我正在与 OSGi 取得联系,现在我有点困惑。我正在使用混合服务模型,这意味着声明性服务和低级 API 的混合。

考虑以下放置在 OSGi-INF/component.xml 下的部分声明:

<property name="canHandle" type="String" value="Some kind of stuff"/>
<service>
  <provide interface="foo"/>
</service>

还有一个

<property name="canHandle" type="String" value="Some other Stuff"/>
<service>
  <provide interface="foo"/>
</service>

在另一个包中,我有这样的东西:

bar.createSomething(String type){

ServiceReference[] services FrameworkUtil.getBundle(getClass()).getBundleContext()
                .getAllServiceReferences("foo");
for (ServiceReference s : services) {
    if (type.equals(s.getProperty("canHandle")){
        Foo foo = (Foo)FrameworkUtilgetBundle(getClass()).getBundleContext().getService(s);
foo.execute();

长话短说,ia 有一个具有多个实现的服务接口,并且在运行时我使用的是一个将字符串与属性匹配的接口。那么我怎样才能只使用声明性服务来处理这种情况呢?

我们正在使用 Virgo,所以如果可以使用 spring,这也是一个选择。

4

1 回答 1

4

您可以使用<reference>元素上的目标过滤器来执行此操作。或者,使用 bnd 注释:

@Reference(target = "(canHandle=blah)")
public void setFoo(Foo foo) {
    // ...
}

现在即使有多个Foo服务实例可用,也只有匹配过滤器的实例(canHandle=blah)才会被注入到您的组件中。

更新

已澄清要匹配的值是静态未知的。在这种情况下,不能使用静态过滤器。但是您仍然可以使用声明式服务并手动检查服务属性的值,例如:

@Reference(multiple = true, dynamic = true)
public void setFoo(Foo foo, Map<String,Object> serviceProps) {
    if ("value".equals(serviceProps.get("canHandle"))) {
        // ...
    }
}

请记住,您现在可能会获得多个匹配的实例。

于 2013-01-14T10:01:20.930 回答