【问题标题】:OSGI Service visibility/DS annotation component injectionOSGI服务可见性/DS注解组件注入
【发布时间】:2020-12-31 12:48:26
【问题描述】:

我有一个由 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 依赖管理器来注入组件:

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 规范来实现这一点,但也希望能够使用工厂方法来实现组件/服务,但我想 OSGI 仍然不支持它,我的意思是,我无法在文档中找到它。

标签: java osgi apache-felix declarative-services felix-dependency-manager


【解决方案1】:

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

【讨论】:

  • 不幸的是,我刚刚发现服务实现需要导出包。这只是一个设计缺陷。
  • 我只是找到了一种方法将服务分成两个不同的包(OSGI 方式)。我解决了我的问题,但是我不能接受你的回答,因为不导出包还是不行。
  • 不确定你的意思。为什么需要两个不同的捆绑包来在捆绑包中提供服务。
  • 这就是我说设计缺陷的原因,因为他们在不同的层面上做事,每个人都有自己的责任
【解决方案2】:

确实,服务注入只有在服务发布到 OSGi 服务注册表时才会起作用。要解决此问题,您可以考虑将“aService”包设为捆绑包的私有,而不是将其导出。这样,aService 将仅在您的 bundle 中声明的组件中可见。

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

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

希望这有帮助吗?

亲切的问候 皮埃尔

【讨论】:

    猜你喜欢
    • 2018-09-19
    • 1970-01-01
    • 1970-01-01
    • 2016-08-05
    • 2013-10-09
    • 2012-11-21
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    相关资源
    最近更新 更多