OSGi中是否有办法确保一次只能访问一项服务?

时间:2011-08-04 13:36:39

标签: osgi declarative-services

我有一个定义系统中设备的界面。这些设备一次只能由一个实体使用。我想将每个设备注册为OSGi服务,以便其他人可以通过该机制访问设备(使用声明式服务或服务跟踪器)。但是,据我所知,该机制允许所有实体请求相同的服务。

是否有办法只让第一个请求者获得服务或使用Declarative Services只有一个服务组件满意?

2 个答案:

答案 0 :(得分:3)

使用ServiceFactory实现设备服务。然后,您可以将唯一的服务对象返回到每个包,然后使用该对象来序列化访问。或者,如果有任何其他捆绑包当前有权访问该服务,则您的ServiceFactory可以向其他捆绑包返回null。

使用ServiceFactory可以让您的服务实现知道哪些bundle正在使用该服务,并对其使用施加一些控制。

答案 1 :(得分:1)

AFAIK您不能使用DS来强制执行单一的消费者政策。

乍一看ServiceFactory 可能会工作,如果确实如此,那将是最简单的方法。

但是有一个caveat"The Framework caches the value returned (unless it is null), and will return the same service object on any future call to BundleContext.getService for the same bundle. This means the Framework must not allow this method to be concurrently called for the same bundle"

所以我认为在以下情况下会失败:

Given Bundle A, Service S and Bundle B;
A gets S, then A ungets S, Bgets S, then A gets S.

框架的缓存可能会干扰并给A缓存的S甚至认为它已被B持有。

我能想到的唯一选择是使用FindHook,虽然这有点低级,你可能想要实现另一个hooks(EventHook,ListenerHook)完整性。

使用钩子,您将能够屏蔽其他捆绑包的服务可用性。虽然你的钩子将保持状态,但你需要它与设备服务在同一个包中,这样就不可能在不停止设备服务捆绑的情况下停止钩子。