【问题标题】:OSGi/Equinox, Declarative Service and Lazy LoadOSGi/Equinox、声明式服务和延迟加载
【发布时间】:2013-06-03 23:19:41
【问题描述】:

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

有两个捆绑包:

-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

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

【问题讨论】:

    标签: java osgi equinox lazy-loading declarative-services


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-12-15
        • 2012-04-27
        • 1970-01-01
        • 1970-01-01
        • 2013-10-09
        • 2018-05-20
        • 1970-01-01
        相关资源
        最近更新 更多