【问题标题】:Does OSGI bundle service consumer need to create "stub" of service interface?OSGI 捆绑服务消费者是否需要创建服务接口的“存根”?
【发布时间】:2013-12-29 21:26:39
【问题描述】:

我刚刚开始亲身体验 OSGI 技术,但基本的查询很少。 这是我所做的:

在名为“com.mypackage.osgi.bundle.service”的包中创建了一个 HelloWorld 接口。这个接口公开了一个方法:public String sayHello(String arg);

在名为“com.mypackage.osgi.bundle.service.impl”的包中创建了一个 HelloWorldImpl 类。该类实现了 HelloWorld 接口,并提供了 sayHello() 方法的实现。

在名为“com.mypackage.osgi.bundle.activator”的包中创建了一个 HelloWorldActivator 类。该类实现了BundleActivator接口,实现了接口的start()和stop()方法。

在 start() 方法中,我通过“BundleContext”将此捆绑包注册为服务。代码如下:

公共类 HelloWorldActivator 实现 BundleActivator {

ServiceRegistration helloServiceRegistration;

public void start(BundleContext context) throws Exception {

    HelloWorld helloService = new HelloWorldImpl();
    helloServiceRegistration =context.registerService(HelloWorld.class.getName(), helloService, null);    System.out.println("Service registered");    }

public void stop(BundleContext context) throws Exception {

    helloServiceRegistration.unregister();    System.out.println("Service un-registered");
} }

然后,我使用 maven 插件将此项目打包为 OSGI 包,并将其部署在 OSGI 容器 (Equinox) 上。在说明中,我将接口公开为导出包。我可以看到我的 OSGI 包已成功部署为 OSGI 容器上的服务(包 id 显示为 ACTIVE 状态,并且我可以在 osgi 控制台上看到“服务注册”输出)。

现在我的下一步是将上述 OSGI 捆绑包作为服务使用。 我知道为了做到这一点,我可以使用“ServiceReference”。

假设我现在正在创建一个完全新的 java 项目(因此该项目的工作区中没有与上面创建的工作区的链接),这样它将充当上面创建的服务的消费者.

我的查询是 - 我需要在这个新的 java 项目中创建 HelloWorld 接口的“副本”吗?换句话说,我需要在这个新项目的工作区中将此接口作为“存根”吗?

我问这个的原因是,如果我在新项目的工作区中没有“HelloWorld”接口的副本,我将在下面提到的第 2 行和第 3 行出现编译错误。

公共类 ConsumerActivator 实现 BundleActivator {

ServiceReference helloServiceReference;

public void start(BundleContext context) throws Exception {

    helloServiceReference= context.getServiceReference(HelloWorld.class.getName()); //2
    HelloWorld helloService =(HelloWorld)context.getService(helloServiceReference); //3
    System.out.println(helloService.sayHello("Test user"));

}
public void stop(BundleContext context) throws Exception {

    context.ungetService(helloServiceReference);
} }

那么,说消费者捆绑包应该有它打算使用的服务接口的“存根”是否正确?

很抱歉,这听起来是一个非常基本的问题,但我需要澄清一下,因为我在网上的任何地方都找不到任何提及它的内容。提供的所有示例都假定消费者和服务都是同一代码工作区的一部分。

非常感谢提前澄清。

最好的问候 磅

【问题讨论】:

    标签: service osgi bundle stub consumer


    【解决方案1】:

    不,只是在两个项目之间建立一个依赖关系。

    另外,如果您刚开始使用 OSGi,那么您真的不应该使用低级 OSGi API。这就像在您学习如何编写 shell 脚本之前尝试破解 Linux 内核!请从声明式服务开始...请参阅此处的教程:http://bndtools.org/tutorial.html

    【讨论】:

    • 谢谢尼尔,但我可能对我的疑问还不够清楚。我要提出的一点是——消费者是否需要了解服务提供者的接口?换句话说,有人说在OSGI环境中有一个名为“com.mypackage.osgi.bundle.service.HelloWorld”注册的服务,任何人都可以使用它。现在,服务消费者是否足以通过仅知道服务的注册名称来使用此服务,或者它需要将此服务接口作为其代码工作区中的存根?
    • 服务消费者需要导入包含服务接口的包,使用Import-Package清单头。接口应该只有一个定义,提供者和消费者都将使用它。
    • 再次感谢您的回复。我同意需要指示 OSGI 容器通过 在服务使用者中导入服务接口。但我的观点是,你仍然需要在消费者的代码工作区中拥有接口代码文件,否则我在原始帖子中提到的代码 sn-p 中的 //2 和 //3 行会产生编译错误。我同意可以创建项目依赖项,但只是认为消费者代码是在完全不知道提供者代码库的另一台机器上创建的。
    • 消费者代码确实需要针对接口进行编译,是的。如果 API、提供者和消费者项目在同一个工作区中,那么您可以创建直接的项目间依赖关系。如果没有,那么您需要一种方法来共享已编译的 API jar。例如,您可以为此使用存储库。
    • 这回答了我的问题。非常感谢!
    【解决方案2】:

    不,最佳做法是将包含接口的单独包作为 API 包的一部分。因此,您可以将接口与实际的服务提供者分开。但是,在您的情况下,这种方法太过分了,我会将 HelloWorld 接口及其(服务)实现放在同一个包中。

    【讨论】:

    • 感谢您的回复。我同意,但我的查询更多地基于依赖关系。让我们假设我们有单独的接口和实现包,但我的疑问是 - 服务使用者如何在其代码工作区中需要接口的副本?
    猜你喜欢
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    • 2013-11-17
    • 2015-01-12
    • 1970-01-01
    相关资源
    最近更新 更多