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

Java OSGI服务可见性/DS注释组件注入,java,osgi,apache-felix,declarative-services,felix-dependency-manager,Java,Osgi,Apache Felix,Declarative Services,Felix Dependency Manager,我有一个由Apache Felix Dependency Manager实例化的服务,因为我需要使用工厂方法来返回实现: manager.add( manager.createComponent() .setInterface(aServiceName, new Properties()) .setFactory(factory, "create")); 因为我希望将此服务注入到同一捆绑包中的服务中,aService和bService都需要位于同一捆

我有一个由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;

    [...]
}
这工作得非常好,问题是我不希望服务在包外可见,就像私有服务一样。 如果我删除:

.setInterface(aServiceName, new Properties())
组件似乎是无论如何都要创建的,但它没有创建,也没有注册为服务,因此其他bundle无法使用它,但我不能使用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)"

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

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

事实上,只有将服务发布到OSGi服务注册中心,服务注入才会起作用。为了工作,你可以考虑让你的“asevice”包私有化,而不是导出它。这样,aService将仅从包中声明的组件可见

现在,也许你也可以考虑用相同的旧“新”关键字来连接你的内部组件(成为你的包的一部分)。请看一下Peter Kriens关于服务组件可见性的有趣回复:

希望这有帮助

问候
Pierre

事实上,只有将服务发布到OSGi服务注册中心,服务注入才会起作用。为了工作,你可以考虑让你的“asevice”包私有化,而不是导出它。这样,aService将仅从包中声明的组件可见

现在,也许你也可以考虑用相同的旧“新”关键字来连接你的内部组件(成为你的包的一部分)。请看一下Peter Kriens关于服务组件可见性的有趣回复:

希望这有帮助

问候
Pierre

我本来希望使用OSGI规范来实现这一点,但也希望能够使用工厂方法来实现组件/服务,但我猜OSGI仍然不支持它,我的意思是,我在文档中找不到它。我本想使用OSGI规范来实现这一点,但也可以使用工厂方法来实现组件/服务,但我猜OSGI仍然不支持它,我的意思是,我在文档中找不到它。不幸的是,我刚刚发现服务实现需要导出包。这只是一个设计缺陷,我只是找到了一种方法将服务分成两个不同的包(OSGI方式)。我解决了我的问题,但我不能接受你的回答,因为不导出包仍然不起作用。不确定你的意思。为什么您需要两个不同的包来在包中提供服务。这就是为什么我说设计缺陷,因为它们在不同的级别上工作,并且每个包都有自己的职责不幸的是,我刚刚发现服务实现需要导出包。这只是一个设计缺陷,我只是找到了一种方法将服务分成两个不同的包(OSGI方式)。我解决了我的问题,但我不能接受你的回答,因为不导出包仍然不起作用。不确定你的意思。为什么您需要两个不同的包来在包中提供服务。这就是为什么我说设计缺陷,因为它们在不同的级别上工作,并且每个包都有自己的责任