我正在尝试使用Declarative Services来创建一个服务包,该服务包为另一个包提供功能。但是,我希望我的服务提供程序包在需要之前不会启动。让我来描述一下我的情况。
有两个捆绑包:
-com.example.serviceprovider
-com.example.serviceconsumer
Service Provider捆绑包使用Declarative Services提供服务,如下所示:
<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
也许我错过了延迟加载捆绑和服务注册的基本概念。如果捆绑包处于“已解决”状态,是否应该连接所有“连线”? (即,有一个类加载器,已解析的导入和导出依赖项和服务已注册。)如果服务使用者试图访问该服务,那么该bundle是否应该转换为“ACTIVE”状态?我在这里错过了什么?
答案 0 :(得分:5)
RESOLVED状态的Bundle无法提供服务,Declarative Services将忽略它们。您通常应该在启动时启动所有捆绑包,即使您需要延迟加载行为。关键是要快速激活捆绑包(或免费!),只需在需要时支付组件的初始化费用。
DS默认情况下负责延迟激活。为此,您无需启用或更改任何内容。本质上,DS在注册表中发布服务条目,但它实际上并不实例化您的组件(甚至加载其类),直到某个客户端尝试使用该服务。
此外,由于DS在需要之前不加载类,OSGi甚至不需要为该包创建ClassLoader,只要您的包没有BundleActivator。
重申一下,你不应该试图让你的捆绑包保持在解决状态。这样的bundle只能导出静态代码和资源,但是它们不能“做”任何事情,也不能参与服务注册。
答案 1 :(得分:2)
声明性服务是针对此案例设计的。启动捆绑包意味着功能应该可用,并不意味着它实际上使用资源。只有在你不想要的时才停止捆绑功能。
这个问题是试图控制太多的好例子。在面向组件的世界中,程序员应该尽可能地使用延迟初始化,但是他们应该从不尝试控制生命周期。