如何正确使用 OSGi getServiceReference() [英] How to use OSGi getServiceReference() right

查看:90
本文介绍了如何正确使用 OSGi getServiceReference()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 OSGi 的新手,遇到过几个关于 OSGi 服务的例子.

I am new to OSGi and came across several examples about OSGi services.

例如:

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());
  }
}

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

My question is, why do you use

getServiceReference(LogService.class.getName())

代替

getServiceReference("LogService")

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

If you use LogService.class.getName() you have to import the Interface. This also means that you have to import the package org.osgi.services.log in your MANIFEST.MF.

如果您想减少依赖以推动松散耦合,这不是完全适得其反吗?据我所知,服务的一个优点是服务消费者不必知道服务发布者.但是如果您必须导入一个特定的接口,您显然必须知道是谁提供的.仅使用像LogService"这样的字符串,您就不必知道接口是由 org.osgi.services.log.LogService 提供的.

Isn't that completely counterproductive if you want to reduce dependencies to push loose coupling? As far as I know one advantage of services is that the service consumer doesn't have to know the service publisher. But if you have to import one specific Interface you clearly have to know who's providing it. By only using a string like "LogService" you would not have to know that the Interface is provided by org.osgi.services.log.LogService.

我在这里遗漏了什么?

推荐答案

看起来你混淆了实现和接口

Looks like you've confused implementation and interface

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

Using the actual interface for the name (and importing the interface , which you'll end up doing anyway) reenforces the interface contract that services are designed around. You don't care about the implemenation of a LogService but you do care about the interface. Every LogService will need to implement the same interface, hence your use of the interface to get the service. For all you know the LogService is really a wrapper around SLF4J provided by some other bundle. All you see is the interface. That's the loose coupling you're looking for. You don't have to ship the interface with every implementation. Leave the interface it's own bundle and have multiple implementations of that interface.

附注:ServiceTracker 通常更易于使用,试试看吧!

Side note: ServiceTracker is usually easier to use, give it a try!

附加好处:使用接口获取类名避免了拼写错误、过多的字符串文字,并使重构更容易.

Added benefits: Using the interface get the class name avoids spelling mistakes, excessive string literals, and makes refactoring much easier.

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

After you've gotten the ServiceReference, your next couple lines will likely involve this:

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");

这篇关于如何正确使用 OSGi getServiceReference()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆