使用DS在OSGi中进行动态目标查询

时间:2012-04-27 18:49:28

标签: osgi

当我在DS中使用引用时,我可以指定一个目标,这将允许我缩小我想要的服务实例。问题是所有示例都显示必须在代码时完成的静态查询。有没有办法进行动态查询(可能从配置管理中提取属性)?

如果DS不支持,那么是否会有另一个支持此功能的OSGi依赖注入框架(蓝图,iPojo等)?

2 个答案:

答案 0 :(得分:7)

您始终可以使用引用的target属性来执行第一级过滤器。如果你的bind方法有签名

void <method-name>(<parameter-type>, Map);

然后,您可以在包含服务属性的Map上运行任何动态过滤器。如果过滤器不匹配,您可以忽略该组件(暂时。)

在替代方案中,由于组件的配置可以包含引用的目标过滤器,因此您可以修改组件的配置以更改目标过滤器。

答案 1 :(得分:5)

我使用以下技巧。如果在服务引用上指定“target”属性但将其值保留为空字符串,则将在运行时使用具有相同名称但后缀为“.target”的组件属性。 / p>

在下面的示例中,我通过Karaf容器中的.cfg文件动态选择我的JDBC源代码。 “datasourcefactory.target”属性自动注入“datasourcefactory”引用的“target”属性。

警告:我实际上并不知道这个技巧是否得到官方支持,或者只是Felix SCR功能。我一直想在规范中查看这一点,看看它是否被提及...... +1澄清其合法性的任何评论!

    @Component(
            name = "...",
            specVersion = "1.1",
            policy = ConfigurationPolicy.REQUIRE,
            metatype = true
    )
    @Property(name = "dataSourceFactory.target",
            value = "",
            label = "dataSourceFactory target",
            description = "An OSGi service filter to select the data source provider. "+
                    "For example: '(&(osgi.jdbc.driver.name=derby)(objectClass=org.osgi.service.jdbc.DataSourceFactory))' where 'derby' is the important bit and the rest is boilerplate. "+
                    "See DataSourceFactory.OSGI_JDBC_DRIVER_(NAME,CLASS,VERSION)."
    )
    @Reference(
            name = "dataSourceFactory",
            referenceInterface = org.osgi.service.jdbc.DataSourceFactory.class,
            cardinality = ReferenceCardinality.MANDATORY_UNARY,
            target = "", // must be overwritten by configuration property named "dataSourceFactory.target"
            bind = "bindDataSourceFactory",
            unbind = "unbindDataSourceFactory"
    )