【发布时间】:2018-02-01 07:18:52
【问题描述】:
在 equinox OSGi 中,我正在使用来自多个不同捆绑包的服务 (DS),并且我想知道服务中谁每次都在使用它。
服务写入数据库,我想知道哪个包写入了什么。
内置的 LogService 必须能够做到这一点,因为它知道每个日志行的编写者,但我不知道如何。
最简单的解决方案是将每个方法中的bundle的名称放到服务中,但我希望有一个更优雅的解决方案。
【问题讨论】:
标签: java osgi osgi-bundle
在 equinox OSGi 中,我正在使用来自多个不同捆绑包的服务 (DS),并且我想知道服务中谁每次都在使用它。
服务写入数据库,我想知道哪个包写入了什么。
内置的 LogService 必须能够做到这一点,因为它知道每个日志行的编写者,但我不知道如何。
最简单的解决方案是将每个方法中的bundle的名称放到服务中,但我希望有一个更优雅的解决方案。
【问题讨论】:
标签: java osgi osgi-bundle
这正是 ServiceFactory 的用途,请参阅 OSGi Core R6 规范第 5.9 节。 “服务工厂”。
在澄清问题以指定 DS 用法后更新如下。
这可以通过在 @Component 注释上使用 scope=ServiceScope.BUNDLE 来实现。然后,您可以通过允许将ComponentContext 注入您的激活方法并调用getUsingBundle() 来访问调用包。例如:
@Component(scope = ServiceScope.BUNDLE)
public class MyComponent implements MyService {
private Bundle usingBundle;
@Activate
void activate(ComponentContext context) {
this.usingBundle = context.getUsingBundle();
}
// ...
}
在底层,这通过将服务注册为ServiceFactory 的实例而不是普通的服务对象来工作。当 OSGi 代表消费者获取服务时,它会调用 getService 方法,该方法将消费者 Bundle 对象传递给服务的提供者。这对消费者来说是完全透明的,即他们根本不需要更改代码。
【讨论】:
将包名称或Bundle 对象添加到您从服务客户端传递到服务的对象。通过这样做,您可以找出每个服务调用的客户端。
您提到了 LogService。它使用LogEntry class 将带有日志消息的Bundle 对象传递给服务。
【讨论】: