OSGi声明性服务在运行时过滤引用

Mic*_*ska 2 service osgi runtime karaf

我一直在尝试使用Karaf上的OSGi声明服务(以及蓝图等)中的一些示例.我现在要解决的问题是如何在运行时获取对某些服务的引用(因此注释和/或XML在这里不是一个真正的选项)

我将解释我的用例:

我正在尝试设计(到目前为止只在我脑海中,这就是为什么我仍然只是试验OSGi :))一个系统来控制工业中的某些自动化过程.为了与设备通信,正在使用一组特殊的协议.为了使组件尽可能可重用,我设计了一个基于层的通信模型(例如用于网络的ISO/OSI模型,但更简单)

要将其转换为OSGi,我系统的每一层都将由一组包组成.一个用于该层的接口,然后是该层的每个实现的一个插件(想象这是OSI的传输层上的TCP与UDP).

要引用此类网络中的任何设备,将使用自定义地址格式(此类地址的两个示例可以是xpa://12.5/03FE或xpb://12.5/03FE).此类地址包含有关访问所请求设备所需的层及其值的所有信息.您可以猜到,此地址的每个部分代表我的网络模型的一层.

这些地址将存储在某个配置数据库中(因此,同样,简单的.cfg或.properties文件不是一个选项),以便可以在运行时远程更改它们.

我正在考虑创建一个Factory,它将解析这个地址,并根据其所有组件创建一个对象链(从OSGi获取适当的服务),实现所有层并相应地配置它们.

由于可以有更多单层实现(因此,实现单个接口的服务更多),这个工厂需要在运行时(当它获取设备地址作为字符串传递时)决定选择哪个特定实现(根据服务将声明的其他属性).

如何在OSGi中实现?对于这个,DS,蓝图或其他什么方法更好?

小智 7

我意识到现在这是对这个问题的一个非常晚的答案,但是两个答案都错过了在Declarative Services中对过滤的明显内置支持.

可以使用@Reference批注为DS引用定义目标过滤器:

@Component
public class ExampleComponent {
    @Reference(target="(foo=bar)")
    MyService myService;
}
Run Code Online (Sandbox Code Playgroud)

也可以使用配置添加(或覆盖)此目标过滤器.对于组件:

@Component(configurationPid="fizz.buzz")
public class ExampleComponent {
    @Reference
    MyService myService;
}
Run Code Online (Sandbox Code Playgroud)

fizz.buzz然后,pid的配置字典可以使用密钥设置新的过滤器myService.target.

这是一个比跳转到原始OSGi API更好的选择,并且可用于多个规范版本.