gpt4 book ai didi

java - 带有组件 XML 文件的 OSGI DeclarativeService Multiton

转载 作者:行者123 更新时间:2023-11-30 10:55:56 25 4
gpt4 key购买 nike

我需要给定 OSGI 组件的多实例,即一些 bundle 将获得相同的实现实例,而其他 bundle 需要另一个实例。如果可能,我需要使用 XML 文件 而不是注释(如 @Component)。我使用的是混合 OSGI 4.3 平台,包含来自 eclipse 和 felix 的 bundle 。

比方说,我的服务界面是这样的:

public interface SocketService {

// Does nothing if already listening on given port
public void startListening(int port);

public String getNextMessage();
}

声明性 XML 文件如下所示并且工作正常:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="SocketService">
<implementation class="declarativemultiton.service.impl.SocketServiceImpl"/>
<service>
<provide interface="declarativemultiton.service.SocketService"/>
</service>
</scr:component>

这些是消费者类,具有相同的语义:

public class Consumer1 {

public void activate() {
System.out.println("Consumer1 activated");
}

public void setSocketService(SocketService service) {
System.out.println("Consumer1 got SocketService@" + System.identityHashCode(service));
}
}

public class Consumer2 {

public void activate() {
System.out.println("Consumer2 activated");
}

public void setSocketService(SocketService service) {
System.out.println("Consumer2 got socketservice@" + System.identityHashCode(service));
}
}

以及它们的组件定义 XML:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Consumer1" immediate="true">
<implementation class="declarativemultiton.consumer1.Consumer1"/>
<reference bind="setSocketService" cardinality="1..1" interface="declarativemultiton.service.SocketService" name="SocketService" policy="static"/>
</scr:component>

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Consumer2" immediate="true">
<implementation class="declarativemultiton.consumer2.Consumer2"/>
<reference bind="setSocketService" cardinality="1..1" interface="declarativemultiton.service.SocketService" name="SocketService" policy="static"/>
</scr:component>

一切都按预期工作,并且两个组件都获得相同的实例:

Socket Service Impl activated
Consumer1 got SocketService@1769618707
Consumer1 activated
Consumer2 got socketservice@1769618707
Consumer2 activated

我需要 Component1 和 Component2 获取不同 SocketService 实例,并且 Component2 和 Component3(未显示)具有相同 SocketService 实例。

如果我将配置策略更改为“要求”,则不会激活消费者组件:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" configuration-policy="require" name="SocketService">
<implementation class="declarativemultiton.service.impl.SocketServiceImpl"/>
<service>
<provide interface="declarativemultiton.service.SocketService"/>
</service>
</scr:component>

这是我迷路的地方,我不知道如何将配置动态传递给 SocketService。在阅读有关 ConfigurationAdmin、ManagedService、ManagedServiceFactory、ComponentFactory 等内容时,我一直在纠结。我找不到一个具体、简洁的解决方案。有一些相互矛盾的方法,比如这个答案 https://stackoverflow.com/a/4129464/330464说不要使用 ManagedService,而是使用 Karaf 教程 http://sully6768.blogspot.com.tr/2012/09/declarative-services-with-karaf-part-4.html解决了它的使用问题。

最佳答案

我认为您使用服务属性来识别或区分使用组件上的 SocketFactory 实例和目标属性以确定使用哪一个是正确的方法,但我建议使用配置而不是每个实现使用多个组件 xml类(class)。我不太清楚您有多少个 SocketFactory 或消费者的实现类。为了说明,我将假设每个人都有一个。

您可以通过 config admin 使用 DS 组件的配置,而不是复制组件 xml 并在那里修改属性。 Peter Kriens 在此处对 DS 包括配置进行了很好的解释: http://enroute.osgi.org/services/org.osgi.service.component.html .以下是一些更详细地涵盖使用配置设置引用的步骤:

  1. 将配置 pid 添加到您的组件 xml。让我们假设 socketFactory 为 socketFactory,消费者为 consumer。

  2. 安装配置管理员。我觉得 felix 和 eclipse 都很好,我只用过 felix。

  3. 在您想要安排套接字工厂启动的包中,执行一些获取 ConfigAdmin 实例的代码并调用类似

    Configuration sfc = ca.createFactoryConfiguration("socketFactory", null);
    Hashtable<String, Object> props = new Hashtable<String, Object>();
    props.put("socketType", "MyType");
    sfc.update(props);

如果此代码与 SocketFactory 代码捆绑在一起,您可以省略 null 参数。这将生成一个带有 socketType=MyType 服务属性的 SocketFactory 组件,类似于您对组件属性所做的操作。

  1. 在要安排消费者设置的 bundle 中,执行类似的操作但使用目标过滤器:

    Configuration cc = ca.createFactoryConfiguration("consumer", null);
    Hashtable<String, Object> props = new Hashtable<String, Object>();
    props.put("SocketService.target", "(socketType=MyType)");
    cc.update(props);

这将生成具有指定目标过滤器的消费者组件。

您也许可以选择使用例如felix fileinstall 从属性文件安装配置。这是非常声明性的,但我没有任何经验,而且我看到有些人很难将所有部分排成一行,因此它可以工作。在工作中,我有幸使用了一个基于 xml 的系统:它从元类型生成一个模式,并将 xml 配置文档(符合生成的模式)与元类型结合以生成配置。它可以从例如生成目标过滤器元素。嵌套的 xml。我经常希望有一个开源版本。

顺便说一句,您可能想重新审视您对 spec ds 注释的回避。它们不在运行时使用,而是在您组装包时由 bnd 处理。 (您正在使用 bnd,不是吗?)。 Bnd 将为与您的组件兼容的尽可能低的 ds 版本生成 component.xml,并且它会比您手动执行更多的验证(至少比我手动执行的要多)。

关于java - 带有组件 XML 文件的 OSGI DeclarativeService Multiton,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33171587/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com