我正在与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();
总而言之,我有一个具有多个实现的服务接口,并且在运行时我使用的是匹配属性的字符串。那么我怎样才能使用声明性服务处理这种情况呢?
我们正在使用处女座,所以如果春天有可能,这也是一个选择。
答案 0 :(得分: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"))) {
// ...
}
}
请记住,您现在可能会获得多个匹配的实例。