【发布时间】:2012-06-24 11:13:45
【问题描述】:
如何通过属性区分实现相同接口的已发布 OSGI 服务?
【问题讨论】:
如何通过属性区分实现相同接口的已发布 OSGI 服务?
【问题讨论】:
假设您要根据某些属性值检索已注册的服务,您需要使用过滤器(基于LDAP 语法)。
例如:
int myport = 5000;
String filter = "&(objectClass=" + MyInterface.class.getName()
+ ")(port=" + myport + ")";
ServiceReference[] serviceReferences = bundleContext.getServiceReferences(null,filter);
您要在其中查找既实现了MyInterface 又具有port 属性值等于myport 的服务。
Here 是获取引用的相关 javadoc。
备注1:
上面的例子和javadoc 参考的是Release 4.2。如果您不限于 J2SE 1.4 运行时,我建议您查看 Release 4.3 syntax,您可以在其中使用泛型。
备注 2:(由 Ray 提供)
您还可以通过从filterStr 字符串创建Filter 对象来预先检查过滤器的正确性:
Filter filter = bundleContext.createFilter(filterStr);
这还允许您将过滤器与其他条件进行匹配。您仍然通过filterStr 来获取引用,因为没有导致Filter 参数的重载。但是请注意,这样您将检查两次正确性:getServiceReferences 和 createFilter 在解析过滤器时抛出 InvalidSyntaxException。我想,这当然不是一个显着的低效率,但值得一提。
【讨论】:
Luca 上面的回答是正确的,但是它假设您使用的是低级 API 来访问服务。
如果您使用的是声明式服务(我通常会推荐),那么可以将过滤器添加到服务引用的target 属性中。例如(使用 DS 的 bnd 注释):
@Reference(target = "(port=8080)")
public void setHttpService(HttpService http) {
// ...
}
【讨论】:
在蓝图中,您可以在引用或引用列表元素上指定过滤器属性。例如:
<reference id="sampleRef"
interface="org.sample.MyInterface"
filter="(port=5000)"/>
【讨论】: