我是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());
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,你为什么要用
getServiceReference(LogService.class.getName())
Run Code Online (Sandbox Code Playgroud)
代替
getServiceReference("LogService")
Run Code Online (Sandbox Code Playgroud)
如果使用LogService.class.getName(),则必须导入接口.这也意味着您必须在MANIFEST.MF中导入包org.osgi.services.log.
如果你想减少依赖性以推动松散耦合,那不是完全适得其反吗?据我所知,服务的一个优点是服务使用者不必知道服务发布者.但是如果你必须导入一个特定的界面,你必须知道谁在提供它.只用像"LogService"的字符串,你就不必知道该接口是由提供org.osgi.services.log.LogService.
我在这里错过了什么?
看起来你已经混淆了实现和界面
使用名称的实际接口(以及导入接口,您最终将完成此操作)会重新获得服务所围绕的接口合约.您不关心LogService的实现,但您确实关心接口.每个LogService都需要实现相同的接口,因此您使用接口来获取服务.大家知道,LogService实际上是一些其他bundle提供的SLF4J包装器.所有你看到的是界面.那是你正在寻找的松耦合.您不必为每个实现提供接口.保留接口它自己的bundle并拥有该接口的多个实现.
旁注:ServiceTracker通常更容易使用,试一试!
增加的好处:使用接口获取类名避免拼写错误,过多的字符串文字,并使重构更容易.
获得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");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12155 次 |
| 最近记录: |