【问题标题】:Search OSGI services by properties按属性搜索 OSGI 服务
【发布时间】:2012-06-24 11:13:45
【问题描述】:

如何通过属性区分实现相同接口的已发布 OSGI 服务?

【问题讨论】:

    标签: java osgi


    【解决方案1】:

    假设您要根据某些属性值检索已注册的服务,您需要使用过滤器(基于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 参数的重载。但是请注意,这样您将检查两次正确性:getServiceReferencescreateFilter 在解析过滤器时抛出 InvalidSyntaxException。我想,这当然不是一个显着的低效率,但值得一提。

    【讨论】:

    • 我只想补充一点,使用 Filter filter = bundleContext.createFilter(filterStr); 验证过滤器语法会很好。首先,仅用于早期的健全性检查,尤其是您的过滤器创建越动态。
    • @Ray:说得好。不幸的是,OSGi 并没有强制(甚至允许)将 Filter 作为参数传递。
    • @LucaGeretti 有没有更聪明的方法来查找声明性 OSGI 服务?
    • @user1474038,如果您使用声明式服务,可以。参考尼尔的回答。
    • 我认为示例文件管理器的语法无效,必须用括号括起来。不使用过滤器作为参数的原因是 getServiceReference(s) 方法级别非常低,不用于应用程序开发。在那个级别,过滤器通常来自一些配置,无论如何通常是一个字符串。如前所述,该方法在过滤器错误时会抛出异常。
    【解决方案2】:

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

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

    @Reference(target = "(port=8080)")
    public void setHttpService(HttpService http) {
        // ...
    }
    

    【讨论】:

    • 我真的希望有一个关于使用 DS(+注释)的详尽教程。尼尔,你知道吗(即使是购买的)?假设 4.2(最多 4.3)。
    • @Ray:就书籍而言,没有人会处理 bnd 注释,因为它们不符合标准。对于 DS,我建议阅读“OSGi 和 Equinox”一书(R4.2,除了“OSGi in Depth”中的一些参考资料外,R4.3 仍然没有书)
    【解决方案3】:

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

    <reference id="sampleRef"
            interface="org.sample.MyInterface"
            filter="(port=5000)"/>
    

    【讨论】:

    • 这不起作用,你得到 Unsatisfied requirements(s): --------------- 服务:(&(service=MyInterface)(port=5000)) [container-name] 启动容器时(类和容器名称已适当更改)。不知道那个错误想说什么。可悲的是,我们正在使用无望记录的保险丝……
    猜你喜欢
    • 2016-05-29
    • 1970-01-01
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-19
    • 2011-10-17
    • 1970-01-01
    相关资源
    最近更新 更多