以编程方式使用 OSGi 中的组件

Posted

技术标签:

【中文标题】以编程方式使用 OSGi 中的组件【英文标题】:Programmatically using components in OSGi 【发布时间】:2012-03-22 21:49:36 【问题描述】:

在我的应用程序中,单独使用服务是毫无用处的。您总是需要一些外部配置信息才能使服务可用。

组件与 ConfigurationAdmin 相结合是有意义的,因为从那时起,对于我创建的每个配置,都会创建一个组件实例。这非常适合我的用例。

现在,问题出现了,如果我想以编程方式使用来自其他包的组件怎么办?这有意义吗?

我知道我可以再次将组件导出为服务,并从其他 bean 中使用它,但是假设我有一个 servlet,用户可以在其中创建配置,并且对于每个配置的实例都有一个操作列表;当他点击动作时,我需要找到合适的组件,并对其执行动作。

在 OSGi 之上实现此功能的最佳方式是什么?

【问题讨论】:

【参考方案1】:

“以编程方式使用来自另一个包的组件”听起来完全对我来说就像 OSGi 服务。

【讨论】:

从配置数据中重新导出自动构建的组件很常见吗? 我不明白你在问什么,你能澄清一下吗? 如果我理解正确,我可以使用 DS 来指定对于每个可用的配置,它应该创建一个组件;就像我有一个连接服务,我想为它创建不同的配置(假设我想有一个串行连接和一个可用的 telnet 连接),那么我可以让 DS 构建两个组件吗?如果是这样,我还可以在不同的接口下注册服务(比如说 Connected),现在该服务也注入了配置数据。对不起这个愚蠢的例子:) 现在我读了回来,ManagedServiceFactory 似乎是一个理想的选择 - 还有什么更好的吗? 对,DS 允许您通过提供多个配置记录来创建组件的多个实例。然而,每个实例都是相同类型的组件:即相同的实现类、相同的已发布服务类型、相同的服务引用等。【参考方案2】:

此方法检索 osgi 服务(iso 让 osgi 容器连接依赖项):

public class ServiceLocator 

  public static <T extends Object> T getService(final Class<T> clazz) 
    final BundleContext bundleContext = FrameworkUtil.getBundle(clazz).getBundleContext();
    // OSGI uses the order of registration if multiple services are found
    final ServiceReference<T> ref =     bundleContext.getServiceReference(clazz);
    return bundleContext.getService(ref);
  

我在现有项目中引入 DS 时使用了此功能,该项目并未在任何地方使用 DS。并非项目中的所有组件都被实例化为 osgi DS 组件。任何我需要访问通过任何其他方式实例化的类中的 DS 组件的地方,我都使用了这个方法......

【讨论】:

以上是关于以编程方式使用 OSGi 中的组件的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式启动 OSGi(Equinox)?

以编程方式为 VueJS 中的动态组件绑定自定义事件

如何以编程方式 ajax 更新支持 bean 中的特定组件

以编程方式连接 LDAP 并在 AEM 中验证凭据

以编程方式添加组件的样式与 XML 布局中的样式不同

以编程方式从 Angular 2 中的 json 创建嵌套组件