service - 如何正确使用 OSGi getServiceReference()

标签 service osgi

我是 OSGi 新手,遇到过几个有关 OSGi 服务的示例。

例如:

import org.osgi.framework.*;
import org.osgi.service.log.*;

public class MyActivator implements BundleActivator {
  public void start(BundleContext context) throws Exception {
    ServiceReference logRef = 
      context.getServiceReference(LogService.class.getName());
  }
}

我的问题是,你为什么使用

getServiceReference(LogService.class.getName())

而不是

getServiceReference("LogService")

如果您使用LogService.class.getName(),则必须导入接口(interface)。这也意味着您必须在 MANIFEST.MF 中导入包 org.osgi.services.log

如果您想减少依赖关系以插入松散耦合,这不是完全适得其反吗?据我所知,服务的优点之一是服务使用者不必知道服务发布者。但如果您必须导入一个特定的接口(interface),您显然必须知道谁提供它。通过仅使用像“LogService”这样的字符串,您不必知道该接口(interface)是由org.osgi.services.log.LogService提供的。

我在这里缺少什么?

最佳答案

看起来您混淆了实现和接口(interface)

使用实际的接口(interface)作为名称(并导入接口(interface),无论如何你最终都会这样做)强化了服务设计所围绕的接口(interface)契约。您不关心 LogService 的实现,但您关心接口(interface)。每个 LogService 都需要实现相同的接口(interface),因此您可以使用该接口(interface)来获取服务。就您所知,LogService 实际上是由其他 bundle 提供的 SLF4J 的包装器。你看到的只是界面。这就是您正在寻找的松散耦合。您不必在每个实现中都附带接口(interface)。将接口(interface)保留为自己的包,并拥有该接口(interface)的多个实现。

旁注:ServiceTracker 通常更容易使用,请尝试一下!

额外的好处:使用接口(interface)获取类名可以避免拼写错误、过多的字符串文字,并使重构变得更加容易。

获得 ServiceReference 后,接下来的几行可能会涉及到以下内容:

Object logSvc = content.getService(logRef)

// What can you do with logSvc now?!? It's an object, mostly useless

// Cast to the interface ... YES! Now you need to import it!
LogSerivce logger = (LogService)logSvc;

logger.log(LogService.LOG_INFO, "Interfaces are a contract between implementation and consumer/user");

关于service - 如何正确使用 OSGi getServiceReference(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2732456/

相关文章:

powershell - 从 powershell 向集群添加通用服务

c# - 如何在Windows服务安装程序中设置 "interact with desktop"

android - 应用强制停止后手动重新启用辅助功能服务不会重新启动

java - Amdatu:如何使 ExceptionMapper (@Provider) 工作?

android - 服务 Intent 必须是明确的 : Intent

java - OSGi bundle 无法启动 - 无法解析 sun.reflect.generics.reflectiveObjects

java - 为什么切换会导致无法解决错误?

java - 激活文件夹中的所有 bundle

java - OSGi 可以安装/部署 URL 上托管的 bundle 吗?

java - 为什么在调用 onDestroy() 时服务不停止