12.5. 访问 OSGi 服务

12.5.1. 概述

本节介绍如何在 OSGi 容器中生成、构建和部署简单的 OSGi 客户端。客户端在 OSGi 注册表中找到一个简单的 Hello World 服务,并调用它上的 sayHello() 方法。

12.5.2. 先决条件

要使用 Maven Quickstart archetype 生成项目,您必须满足以下条件:

  • Maven 安装- Maven 是一个来自 Apache 的免费开源构建工具。您可以从 http://maven.apache.org/download.html 下载最新版本(最小为 2.0.9)。
  • 互联网连接-whilst 执行构建,Maven 会动态搜索外部存储库,并即时下载所需的工件。要使此任务正常工作,构建 机器必须 连接到互联网。

12.5.3. 生成 Maven 项目

maven-archetype- Quickstart archetype 创建一个通用 Maven 项目,然后您可以根据您需要的任何用途进行自定义。要使用协调( org.fusesource.example:osgi-client )生成 Maven 项目,请输入以下命令:

mvn archetype:create
-DarchetypeArtifactId=maven-archetype-quickstart
-DgroupId=org.fusesource.example
-DartifactId=osgi-client

此命令的结果是目录 ProjectDir/osgi-client,其中包含生成的项目的文件。

注意

请注意 ,不要为您的工件选择一个组 ID,该 ID 与现有产品的组 ID 冲突!这可能会导致项目的软件包和现有产品中的软件包与来自现有产品的软件包之间的冲突(因为组 ID 通常被用作项目 Java 软件包名称的根目录)。

12.5.4. 自定义 POM 文件

您必须自定义 POM 文件才能生成 OSGi 捆绑包,如下所示:

  1. 按照 第 5.1 节 “生成捆绑包项目” 中描述的 POM 自定义步骤操作。
  2. 由于客户端使用 HelloWorldSvc Java 接口(在 osgi-service 捆绑包中定义),因此需要对 osgi-service 捆绑包添加 Maven 依赖项。假设 osgi-service 捆绑包的 Maven 协调为 org.fusesource.example:osgi-service:1.0-SNAPSHOT,您应该在客户端的 POM 文件中添加以下依赖关系:

    <project ... >
      ...
      <dependencies>
        ...
        <dependency>
            <groupId>org.fusesource.example</groupId>
            <artifactId>osgi-service</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
      </dependencies>
      ...
    </project>

12.5.5. 编写 Blueprint 文件

要将 Blueprint 文件添加到客户端项目,请首先创建以下子目录:

ProjectDir/osgi-client/src/main/resources
ProjectDir/osgi-client/src/main/resources/OSGI-INF
ProjectDir/osgi-client/src/main/resources/OSGI-INF/blueprint

ProjectDir/osgi-client/src/main/resources/OSGI-INF/blueprint 目录下,使用您首选的文本编辑器创建文件 config.xml,并从 例 12.6 “用于导入服务的蓝图文件” 添加 XML 代码。

例 12.6. 用于导入服务的蓝图文件

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">

  <reference id="helloWorld"
        interface="org.fusesource.example.service.HelloWorldSvc"/>

  <bean id="client"
        class="org.fusesource.example.client.Client"
        init-method="init">
    <property name="helloWorldSvc" ref="helloWorld"/>
  </bean>

</blueprint>

其中 参考 元素会创建一个参考管理器,该管理器在 OSGi 注册表中找到 HelloWorldSvc 类型的服务。bean 元素会创建一个 Client 类的实例,并注入服务引用作为 bean 属性 helloWorldSvc。此外,init-method 属性指定在 bean 初始化阶段调用 Client.init() 方法(即,在服务引用注入客户端 bean 后)。

12.5.6. 编写客户端类

ProjectDir/osgi-client/src/main/java/org/fusesource/example/client 目录下,使用您首选的文本编辑器创建文件 Client.java,并从 例 12.7 “Client Class” 添加 Java 代码。

例 12.7. Client Class

package org.fusesource.example.client;

import org.fusesource.example.service.HelloWorldSvc;

public class Client {
    HelloWorldSvc helloWorldSvc;

    // Bean properties
    public HelloWorldSvc getHelloWorldSvc() {
        return helloWorldSvc;
    }

    public void setHelloWorldSvc(HelloWorldSvc helloWorldSvc) {
        this.helloWorldSvc = helloWorldSvc;
    }

    public void init() {
        System.out.println("OSGi client started.");
        if (helloWorldSvc != null) {
            System.out.println("Calling sayHello()");
            helloWorldSvc.sayHello();  // Invoke the OSGi service!
        }
    }

}

Client 类为 helloWorldS vcan 属性定义一个 getter 和 setter 方法,它可以通过注入来接收 Hello World 服务的引用。init() 方法在 bean 初始化阶段调用,在属性注入后,这通常可以在此方法范围内调用 Hello World 服务。

12.5.7. 运行客户端捆绑包

要安装并运行 osgi-client 项目,请执行以下步骤:

  1. 构建项目- 打开命令提示并将目录更改为 ProjectDir/osgi-client。使用以下命令构建演示:

    mvn install

    如果此命令成功运行,则 ProjectDir/osgi-client/target 目录应包含捆绑包文件 osgi-client-1.0-SNAPSHOT.jar

  2. 在 Red Hat Fuse 控制台中安装 并启动 osgi-service 捆绑包,请输入以下命令:

    karaf@root()> bundle:install -s file:ProjectDir/osgi-client/target/osgi-client-1.0-SNAPSHOT.jar

    其中 ProjectDir 是包含 Maven 项目的目录,而 -s 标志会指示容器立即启动捆绑包。例如,如果您的项目目录是 Windows 机器上的 C:\Projects,则使用以下命令:

    karaf@root()> bundle:install -s file:C:/Projects/osgi-client/target/osgi-client-1.0-SNAPSHOT.jar
    注意

    在 Windows 机器中,请注意如何对 文件 URL 进行格式化,以了解 文件 URL 处理程序所了解的语法详情,请参考 第 15.1 节 “文件 URL 处理程序”

  3. 客户端输出-f 客户端捆绑包成功启动,您应该在控制台中立即看到类似如下的输出:

    Bundle ID: 239
    OSGi client started.
    Calling sayHello()
    Hello World!