我有osgi服务service-1.0.0.jar和service-1.1.0.jar他们是service-api-1.0.0.jar的实现
这些service-1.0.0.jar和service-1.1.0.jar都具有相同的服务名称和包。
服务由bundle-activator注册
假设bundle激活器是com.abc.xyz.MyActivator - 1.0.0和1.1.0
我面临的问题是,当我部署这些服务并使用服务跟踪器进行查找并对我想要的版本进行过滤时,无论选择何种版本,我都会得到相同的实现。
这让我相信我想要实现的目标是不可行的。 我需要在不同版本的捆绑包中打包的多个服务实现,并且能够在运行时动态选择。
我在jboss-6.1.1 eap
中尝试这个如果我在版本中保留不同的包名称,看起来它能够理解这些是2种不同的服务,但是当包名称相同时,我得到相同的服务实现。
我做错了什么?有人试过吗?OSGI允许您部署多个服务版本是否正确?
更新 在1.0.0和1.1.0中为MyActivator使用唯一程序包名称后,服务可以保持唯一性。
这是否意味着Activators必须在捆绑包中独一无二?
答案 0 :(得分:1)
我假设service-api-1.0.0.jar
导出定义服务接口的包。在这种情况下,听起来你有两个相同版本的服务实现。不同版本的服务没有不同的实现。所以从服务用户的角度来看,服务是相同的:它们来自相同的服务api包版本。
答案 1 :(得分:1)
我认为你是以一种奇怪的方式使用OSGi服务。作为客户端,您不应该查看实现包以确定版本或其他信息。
相反,您应该使用服务接口和服务属性来区分服务。
因此,例如,您可以拥有属性版本并发布版本= 1的第一个服务,以及版本= 2的第二个服务。然后,您可以筛选此属性以获取特定服务。
使用反射也是一件相当不寻常的事情。最好尝试在用于在客户端和服务之间交换数据的接口包中提供类。这将使客户端减少对服务impl的依赖。
答案 2 :(得分:0)
如果您有多个相同服务API的实现,并且客户端查询服务API的实现,则它可以获得任何实现。这很好,因为客户不应该关心。
例如,假设您有一个Greeting
接口,其中多个实现已注册为服务,可能是多个捆绑包。如果客户端要求OSGi提供Greeting
服务,那么OSGi将只选择一个。毕竟,如果只是要求Greeting
而没有指定任何其他内容,那么您应该接受任何实现。客户当然不应该关心服务来自哪个特定的捆绑:这是脱钩的本质。
顺便提一下,当发生这种情况时,OSGi通常会选择首先注册的实现(实际上是service.id
最低的实现,这是一个不断递增的数字,所以它实际上是相同的事情)。这可能是您看到OSGi一直选择一项特定服务的原因。
如果您的客户需要区分服务实现,那么您可以向已发布的服务添加属性并过滤这些服务。例如,一个捆绑包可以发布具有属性language=en_US
的Greeting服务(即美国英语),另一个捆绑包可以发布具有language=de
的Greeting服务。如果您的客户只想用英语问候,那么它可以使用像(language=en*)
这样的过滤器。