3

我正在尝试使用声明式服务来创建一个为另一个包提供功能的服务包。但是,我希望我的服务提供程序包在需要时才启动。让我描述一下我的情况。

有两个捆绑包:

-com.example.serviceprovider

-com.example.serviceconsumer

Service Provider bundle 使用声明式服务提供服务,如下所示:

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" enabled="true"     immediate="true" name="samplerunnable1">
<implementation class="com.example.serviceprovider.SampleRunnable"/>
<service>
    <provide interface="java.lang.Runnable"/>
</service>

服务消费者引用提供的服务如下:

<reference name="SampleRunnable"
    interface="java.lang.Runnable"
    bind="setRunnable"
    unbind="unsetRunnable"
    cardinality="1..n"
    policy="dynamic"/>

当这两个捆绑包在启动时都处于“活动状态”时,服务消费者与服务提供者声明的服务进行通信就没有问题。当我尝试让服务提供商以懒惰的方式启动时,就会出现问题。

在服务提供者设置为延迟加载之后,这就是我在 OSGi 控制台中得到的:

osgi> ss
  "Framework is launched."
  id      State       Bundle
  15      STARTING    com.example.serviceconsumer_1.0.0.X
  16      RESOLVED    com.example.serviceprovider_1.0.0.X

我希望看到的是,即使捆绑 16 只是“已解决”,它至少会注​​册的是服务。但是当我调用“捆绑”命令时,它会显示“没有注册服务”。

osgi> bundle 16
com.example.serviceprovider_1.0.0.X [17]
  Id=17, Status=RESOLVED    Data Root=C:\apache\apache-tomcat-.0.40\work\Catalina\localhost\examplesX\eclipse\configuration\org.eclipse.osgi\bundles\17\data
  "No registered services."
  No services in use.
  No exported packages
  Imported packages
     org.osgi.framework; version="1.7.0"<org.eclipse.osgi_3.8.0.v20120529-1548 [0]>
  No fragment bundles
  Named class space
    com.example.serivceprovider; bundle-version="1.0.0.X"[provided]
  No required bundles

也许我错过了延迟加载包和服务注册的基本概念。如果捆绑包处于“已解决”状态,它不应该连接所有“电线”吗?(即,有一个类加载器、解析的导入和导出依赖项以及注册的服务。)如果服务消费者尝试访问服务,该捆绑包不应该转换到“活动”状态吗?我在这里缺少什么?

4

2 回答 2

5

处于 RESOLVED 状态的 Bundle 无法提供服务,它们将被声明式服务忽略。您通常应该在启动期间启动所有捆绑包,即使您想要延迟加载行为。关键是使捆绑包的激活便宜(或免费!),并且仅在需要时为组件的初始化付费。

默认情况下,DS 已经处理了延迟激活。您无需启用或更改任何内容即可实现此目的。本质上,DS 在注册表中发布服务条目,但在某些客户端尝试使用该服务之前,它实际上并不实例化您的组件(甚至加载其类)。

此外,因为 DS 在需要时才加载类,所以 OSGi 甚至不需要为包创建 ClassLoader,只要您的包没有 BundleActivator。

重申一下,你不应该试图让你的包保持在 RESOLVED 状态。此类捆绑包只能导出静态代码和资源,但不能“做”任何事情,也不能参与服务注册中心。

于 2013-06-07T16:58:27.807 回答
2

声明式服务是为这种情况设计的。启动一个包意味着它的功能应该可用,并不意味着它实际使用资源。仅当您不想要功能时才停止捆绑。

这个问题是试图控制太多的一个很好的例子。在面向组件的世界中,程序员应该尽可能地使用惰性初始化,但他们不应该尝试控制生命周期。

于 2013-06-08T17:14:10.257 回答