12.2. 导出服务
概述
这部分论述了如何将 Java 对象导出到 OSGi 服务 registry,从而使它可作为服务来访问 OSGi 容器中的其他捆绑包。
使用单个接口导出
要在一个接口名称下将服务导出到 OSGi 服务
registry,请使用 ref
属性定义引用相关服务 bean 的服务元素,并使用 interface 属性指定已发布的 接口
。
例如,您可以使用 例 12.1 “使用单一接口进行服务导出示例” 中显示的 Blueprint 配置代码,在 org.fusesource.example.Account
接口名称下导出 SavingsAccountImpl
类的实例。
例 12.1. 使用单一接口进行服务导出示例
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<bean id="savings" class="org.fusesource.example.SavingsAccountImpl"/>
<service ref="savings" interface="org.fusesource.example.Account"/>
</blueprint>
其中 ref
属性指定对应的 bean 实例的 ID,而 interface
属性指定服务在 OSGi 服务注册表中注册的公共 Java 接口的名称。本例中使用的类别和接口如下所示 例 12.2 “帐户类和接口示例”
例 12.2. 帐户类和接口示例
package org.fusesource.example public interface Account { ... } public interface SavingsAccount { ... } public interface CheckingAccount { ... } public class SavingsAccountImpl implements SavingsAccount { ... } public class CheckingAccountImpl implements CheckingAccount { ... }
使用多个接口导出
要在多个接口名称下将服务导出到 OSGi 服务
registry,请使用 ref
属性定义引用相关服务 bean 的服务元素,并使用 interfaces
子元素指定已发布的接口。
例如,您可以在公共 Java 接口列表下导出 SavingsAccountImpl
类的实例,org.fusesource.example.Account
和 org.fusesource.example.SavingsAccount
,使用以下 Blueprint 配置代码:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> <bean id="savings" class="org.fusesource.example.SavingsAccountImpl"/> <service ref="savings"> <interfaces> <value>org.fusesource.example.Account</value> <value>org.fusesource.example.SavingsAccount</value> </interfaces> </service> ... </blueprint>
interface
属性和 interfaces
元素无法同时在同一 服务
元素中使用。您必须使用一个或另一个。
使用自动导出导出
如果要在其实施的公共 Java 接口下将服务导出到 OSGi 服务 registry,那么使用 auto-export
属性即可轻松完成此操作。
例如,要在所有实施的公共接口下导出 SavingsAccountImpl
类的实例,请使用以下 Blueprint 配置代码:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> <bean id="savings" class="org.fusesource.example.SavingsAccountImpl"/> <service ref="savings" auto-export="interfaces"/> ... </blueprint>
auto-export
属性的 interfaces
值表示 Blueprint 应该注册通过 节省sAccountImpl
实施的所有公共接口。auto-export
属性可以具有以下有效值:
disabled
- 禁用自动导出。这是默认值。
interfaces
- 将该服务注册到所有实施的公共 Java 接口。
class-hierarchy
-
将服务注册到自己的类型(class)下,并在除
Object
类外的所有超级用户(su-types(super-classes)下注册。 all-classes
-
与
class-hierarchy
选项一样,包括所有已实施的公共 Java 接口。
设置服务属性
OSGi 服务 registry 还允许您将服务 属性 与注册的服务相关联。然后,服务的客户端可以使用服务属性来搜索或过滤服务。要将服务属性与导出服务关联,请添加 service-properties
子元素,其中包含一个或多个 Bean:entry
元素(每个服务属性的一个 Bean:entry
元素)。
例如,要将 bank.name
字符串属性与节省的帐户服务相关联,您可以使用以下蓝图配置:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:beans="http://www.springframework.org/schema/beans" ...> ... <service ref="savings" auto-export="interfaces"> <service-properties> <beans:entry key="bank.name" value="HighStreetBank"/> </service-properties> </service> ... </blueprint>
银行.name
字符串属性具有值 HighStreetBank
。可以对字符串以外的类型定义服务属性:即,支持原语类型、数组和集合。有关如何定义这些类型的详情,请参阅 Spring 参考指南 中的 控制 Advertised Properties 设置。
属于 Blueprint 命名空间 的条目
元素。在 Spring 的蓝图实施中的 Bean:entry
元素是非标准。
默认服务属性
使用 service
元素导出服务时可能会自动设置两个服务属性,如下所示:
-
os.service.blueprint.compname
-is 始终设置为服务的bean
元素的id
,除非被嵌入(即,bean 定义为服务
元素的子元素)。内联 Bean 始终是匿名的。 -
service.ranking
-is 会自动设置,如果 ranking 属性为零。
指定 ranking 属性
如果捆绑包在服务 registry 中查找一个服务并找到多个匹配的服务,您可以使用等级确定是否返回哪些服务。该规则是,每当查找匹配多个服务时,返回具有最高等级的服务。服务等级可以是任何非负的整数,其中 0
是默认值。您可以通过设置 service
元素 上的
ranking 属性来指定服务等级:
<service ref="savings" interface="org.fusesource.example.Account" ranking="10"/>
指定注册监听程序
如果要跟踪服务注册和取消注册事件,您可以定义一个 注册和取消注册事件通知的注册监听程序 回调。要定义注册监听程序,请将 registration-listener
子元素添加到 服务
元素中。
例如,以下 blueprint 配置定义了一个监听器 bean, listenerBean
,它被 registration-listener
元素引用,以便在 帐户
服务注册或取消注册时收到回调:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" ...> ... <bean id="listenerBean" class="org.fusesource.example.Listener"/> <service ref="savings" auto-export="interfaces"> <registration-listener ref="listenerBean" registration-method="register" unregistration-method="unregister"/> </service> ... </blueprint>
如果 registration-listener
元素的 ref
属性引用侦听器的 id
,registration-method
属性指定接收注册回调的监听程序方法的名称,而 unregistration-method
属性指定接收非注册回调的监听程序方法的名称。
以下 Java 代码显示了 Listener
类的示例定义,接收注册和取消注册事件的通知:
package org.fusesource.example; public class Listener { public void register(Account service, java.util.Map serviceProperties) { ... } public void unregister(Account service, java.util.Map serviceProperties) { ... } }
方法名称、注册和
取消注册
分别由 registration-method
和 unregistration-method
属性指定。这些方法的签名必须符合以下语法:
-
第一个参数- 任何可从服务对象类型分配的 T 类型。换句话说,服务类的任何超级类型类或任何由服务类实施的接口。此参数包含服务实例,除非 service bean 声明了要进行设计
的范围
(在本例中为 null 时(当范围为null
时,没有服务实例在注册时没有可用)。 -
第二个方法参数- 必须为
java.util.Map
类型或java.util.Dictionary
类型。此映射包含与此服务注册关联的服务属性。