12.2. 导出服务
概述
这部分描述了如何将 Java 对象导出到 OSGi 服务注册表,从而使它可作为 service 到 OSGi 容器中其他捆绑包的服务。
使用单个接口导出
要在单一接口名称下将服务导出到 OSGi 服务注册表,请定义一个 service
元素来引用相关服务 bean,使用 ref
属性指定发布的接口,并使用 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 服务注册表,请定义一个 service
元素来引用相关服务 bean,使用 ref
属性指定公布的接口,并使用 interfaces
子元素指定发布的接口。
例如,您可以使用以下 Blueprint 配置代码在公共 Java 接口列表下导出 Savings
类的实例: Account
Impl
<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
元素不能在同一 service
元素中同时使用。您必须使用一个或多个.
使用自动导出导出
如果要在 其所有 实施的公共 Java 接口下将服务导出到 OSGi 服务注册表,则可以使用 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
属性 的接口
值表示 Blueprint 应注册 SavingsAccountImpl
实施的所有公共接口。auto-export
属性可以具有以下有效值:
disabled
- 禁用自动导出。这是默认值。
interfaces
- 将服务注册到其所有实施的公共 Java 接口下。
class-hierarchy
-
将服务注册到其自己的类型(class),并在所有 super-types (super-classes)下注册,但对象类除外。
all-classes
-
与
class-hierarchy
选项类似,但还包括所有实施的公共 Java 接口。
设置服务属性
OSGi 服务注册表还允许您将服务属性与注册 的服务 相关联。然后,服务的客户端可以使用服务属性来搜索或过滤服务。要将服务属性与导出的服务关联,请添加一个 service-properties
子元素,其中包含一个或多个 beans:entry
元素(每个服务属性有一个 beans:entry
元素)。
例如,要将 bank.name
字符串属性与节省帐户服务相关联,您可以使用以下 Blueprint 配置:
<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>
其中 bank.name
字符串属性具有值 HighStreetBank
。可以定义字符串以外的类型的服务属性:即,也支持原语类型、数组和集合。有关如何定义这些类型的详情,请参阅 Spring 参考指南 中的 控制公告属性 集。
条目
元素 ought 属于 Blueprint 命名空间。Spring 的蓝图实现中的 beans:entry
元素的使用是非标准。
默认服务属性
使用 service
元素导出服务时可能会自动设置两个服务属性,如下所示:
-
osgi.service.blueprint.compname
-is 始终设置为服务的bean
元素的id
,除非 bean 被内联(即,bean 被定义为service
元素的子元素)。内联 Bean 始终是匿名的。 -
如果 ranking 属性为零,则会自动设置
service.ranking
-is。
指定等级属性
如果捆绑包在服务 registry 中查找服务并找到多个匹配服务,您可以使用等级来确定返回哪些服务。规则是,每当查找与多个服务匹配时,会返回具有最高等级的服务。服务等级可以是任何非负整数,0
是默认值。您可以通过在 service
元素上设置 ranking
属性来指定服务等级,例如:
<service ref="savings" interface="org.fusesource.example.Account" ranking="10"/>
指定注册监听程序
如果要跟踪服务注册和未注册事件,您可以定义接收 注册和未注册事件通知的注册监听程序 回调 Bean。要定义注册监听程序,请在 service
元素中添加 registration-listener
子元素。
例如,以下 Blueprint 配置定义了一个监听器 bean bean, listenerBean
,它由 registration-listener
元素引用,以便在 帐户
服务注册或取消注册时监听程序 bean 接收回调:
<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
属性引用监听器 bean 的 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) { ... } }
方法名称 register
和 unregister
分别由 registration-method
和 unregistration-method
属性指定。这些方法的签名必须符合以下语法:
-
第一方法参数- 从服务对象类型分配的任何类型 T。换句话说,服务类或由服务类实施的任何接口的超级类型类。此参数包含服务实例,除非服务 bean 声明了要
原型化
的范围
,在这种情况下,此参数为null
(当范围是原型
的时,在注册时没有服务实例可用)。 -
第二种方法参数- 必须是
java.util.Map
类型或java.util.Dictionary
类型。此映射包含与此服务注册关联的服务属性。