OSGI服务可见性/ DS注释组件注入

问题描述

我有一个由Apache Felix Dependency Manager实例化的服务,因为我需要使用工厂方法来返回实现:

manager.add(
    manager.createComponent()
    .setInterface(aServiceName,new Properties())
    .setFactory(factory,"create"));

因为我希望将此服务注入到同一捆绑包内的服务中,所以 aService和bService都必须位于同一捆绑包中

@Component
public class BService {

    @Reference
    private AService aService;

    [...]
}

这工作得很好,问题是我不希望aService在捆绑包之外可见,就像私人服务一样。 如果我删除

.setInterface(aServiceName,new Properties())

该组件似乎仍然要创建的未创建,并且未注册为服务,因此无法用于其他捆绑软件,但是我无法使用DS注释注入该组件。 真的不可能使服务仅在产生它的捆绑包内可见吗?还是有办法仍然注入带有DS批注的组件?

我尝试使用Apache Felix Dependency Manager注入组件:

import org.apache.Felix.dm.annotation.api.Component;
import org.apache.Felix.dm.annotation.api.ServiceDependency;

@Component
public class BService {

    @ServiceDependency
    private AService aService;

    [...]
}

但我发现该组件未注入:

[32] org.apache.Felix.dependencymanager.runtime
 [0] org.apache.Felix.dm.runtime.DependencyManagerRuntime registered
     active (DependencyManager-Component=*) bundle optional available
     org.osgi.service.packageadmin.PackageAdmin service required available
     org.osgi.service.log.LogService service optional available
[131] [...]
  [7] [...].BService unregistered
      org.osgi.service.log.LoggerFactory service required available
      [...].AService service required unavailable

这是否意味着我不能使用@ServiceDependency注入简单的组件,因为它们必须是服务,因此必须存在Osgi注册表中?然后如何使用注解注入简单的组件?应该有一个,对吧?

更新

我刚刚意识到aService实现需要导出包,因此这只是一个设计缺陷。然后,我只是找到了一种将服​​务分成两个不同的捆绑包的方法(Osgi方法)并解决了我的问题。

在此之前,我尝试从导出的​​捆绑软件中删除软件包,但仍然无法正常工作,该服务仍然可用。

Export-Package: [...].services;version="0.0.1"
Provide-Capability: osgi.service;uses:="[...].services";o
 bjectClass="[...].services.BService",osgi.service;uses:=
 "[...].services.internal";objectClass="[...].services.internal.AService"
Require-Capability: osgi.extender;filter:="(&(osgi.extender=osgi.compo
nent)(version>=1.4.0)(!(version>=2.0.0)))",osgi.service;effective:=ac
tive;filter:="(objectClass=[...].services.internal.AServ
ice)"

解决方法

要创建仅在包内可见的服务,只需确保您不导出服务接口的包即可。这样,其他捆绑包将不会看到或使用该服务。

,

实际上,只有在将服务发布到OSGi服务注册表中时,服务注入才起作用。要变通解决,您可以考虑将“ aService”软件包专用于捆绑软件,而不是将其导出。这样,aService仅在捆绑软件内部声明的组件中可见。

现在,也许您还可以考虑使用相同的旧“ new”关键字来连接内部组件(属于捆绑软件的一部分)?请查看Peter Kriens关于服务组件可见性的有趣回复:

https://www.mail-archive.com/users@felix.apache.org/msg16349.html

希望这有帮助吗?

亲切的问候 皮埃尔