Java 按属性搜索OSGI服务

Java 按属性搜索OSGI服务,java,osgi,Java,Osgi,如何根据属性区分实现相同接口的已发布OSGI服务 假设您希望根据属性的某些值检索已注册的服务,则需要使用过滤器(基于语法) 例如: int myport = 5000; String filter = "&(objectClass=" + MyInterface.class.getName() + ")(port=" + myport + ")"; ServiceReference[] serviceReferences = bundleContext.

如何根据属性区分实现相同接口的已发布OSGI服务

假设您希望根据属性的某些值检索已注册的服务,则需要使用过滤器(基于语法)

例如:

int myport = 5000;
String filter = "&(objectClass=" + MyInterface.class.getName() 
                + ")(port=" + myport + ")";
ServiceReference[] serviceReferences = bundleContext.getServiceReferences(null,filter);
<reference id="sampleRef"
        interface="org.sample.MyInterface"
        filter="(port=5000)"/>
您希望在其中查找实现
MyInterface
port
属性值等于
myport
的服务

是获取引用的相关javadoc

备注1:

上面的示例和javadoc参考了4.2版。如果您不局限于J2SE 1.4运行时,我建议您看看4.3版,在那里您可以使用泛型

备注2:(雷提供)

您也可以通过从
filterStr
字符串创建对象来预先检查过滤器的正确性:

Filter filter = bundleContext.createFilter(filterStr);  

这还允许您将筛选器与其他条件匹配。您仍然要传递
filterStr
来获取引用,因为不存在导致
Filter
参数的重载。但是,请注意,通过这种方式,您将检查两次正确性:解析筛选器时,同时检查
getservicerences
createFilter
throw
InvalidSyntaxException
。我想,这肯定不是一种效率低下的表现,但值得一提

上面Luca的回答是正确的,但是它假设您正在使用低级API访问服务

如果您使用的是声明性服务(我通常会推荐),那么可以将过滤器添加到服务引用的
target
属性中。例如(使用DS的bnd注释):


在Blueprint中,可以在引用或引用列表元素上指定过滤器属性。例如:

int myport = 5000;
String filter = "&(objectClass=" + MyInterface.class.getName() 
                + ")(port=" + myport + ")";
ServiceReference[] serviceReferences = bundleContext.getServiceReferences(null,filter);
<reference id="sampleRef"
        interface="org.sample.MyInterface"
        filter="(port=5000)"/>


我要补充的是,最好使用filter filter=bundleContext.createFilter(filterStr)验证过滤器语法;首先,只是为了早期的健全性检查,特别是过滤器创建的动态性越强。@Ray:说得好。不幸的是,OSGi不强制(甚至不允许)将筛选器作为参数传递。@LucaGeretti还有其他更聪明的方法来查找声明性OSGi服务吗?@user1474038,如果您使用声明性服务,是的。参考Neil的回答,我认为示例文件管理器的语法无效,必须用括号括起来。筛选器未用作参数的原因是getServiceReference方法的级别非常低,不用于应用程序开发。在这个级别上,过滤器通常来自一些配置,这些配置通常是一个字符串。如前所述,当筛选器出错时,该方法会引发异常。我真希望有一个关于使用DS(+注释)的完整教程。尼尔,你知道有一个吗(即使是买的)?假设是4.2(最多4.3)。@Ray:就书籍而言,没有一本会处理bnd注释,因为它们不在标准上。对于DS,我建议使用“OSGi和Equinox”一书(R4.2,除了“OSGi深入”中的一些参考文献外,R4.3仍然没有其他书),但这本书不起作用,在启动容器时,您会得到未满足的要求:-------------------------------服务:(&(service=MyInterface)(port=5000))[container name](类和容器名称适当更改)。不知道该错误试图说明什么。遗憾的是,我们使用的是毫无希望的fuse文档。。。