如何注销 OSGi 服务

how to unregister an OSGi service

我有以下测试代码,应该注册和取消注册测试服务。我在 Eclipse 4.5.2 Mail-Demo 应用程序中对其进行了测试。问题是服务没有注销,第二次调用服务不为空

BundleContext bundleContext = Activator.getDefault().getBundle().getBundleContext();

ServiceRegistration<ITestService> registration = bundleContext.registerService(ITestService.class, new TestService(), null);

ServiceReference<ITestService> serviceReference = bundleContext.getServiceReference(ITestService.class);
bundleContext.ungetService(serviceReference);

serviceReference = bundleContext.getServiceReference(ITestService.class);
System.out.println("should be null but is not: " + serviceReference);

这是我得到的输出:

should be null but is not: {unregister.osgiservice.ITestService}={service.id=172, service.bundleid=8, service.scope=singleton}

如何正确注销服务?


编辑:
好的,我发现 ServiceRegistration.unregister(),如果我在下面添加代码,则服务未注册。这就引出了下一个问题,我如何从注册服务的另一个地方获取 ServiceRegistration

registration.unregister();

serviceReference = bundleContext.getServiceReference(ITestService.class);
System.out.println("now the service is null: " + serviceReference);

输出:

should be null but is not: {unregister.osgiservice.ITestService}= service.id=174, service.bundleid=8, service.scope=singleton}
now the service is null: null

ungetService 只是删除特定的服务引用,它不会注销服务。

registerService returns 一个 ServiceRegistration 可以用来注销服务:

ServiceRegistration<ITestService> reg = bundleContext.registerService(ITestService.class, new TestService(), null);

...

reg.unregister();

跟踪服务注册由您决定。许多插件将它们存储在插件 Activator 中。在Activatorstart方法中注册服务,在stop方法中注销也很常见。

尽管上面有 greg 的回答,但我发现这个讨厌的解决方法是使用内部 类:

((org.eclipse.osgi.internal.serviceregistry.ServiceReferenceImpl) serviceReference).getRegistration().unregister();

当然这很糟糕,但我需要一个解决方案来获得 ServiceRegistration。我无法在启动时存储 ServiceRegistration,因为我正在使用 Eclipse Gemini Blueprint(以前的 Spring DM)来注册我的服务。