当前位置: 首页 > 知识库问答 >
问题:

在OSGi felix scr注释中将运行时参数传递给服务

司空鸿熙
2023-03-14

我正在开发一个OSGi应用程序(带有felix scr注释),它公开了一个服务。服务通过传递字符串值向外部api注册。

listener.addSchemaChangeListener(new ChangeListener()
{
    @Override
    public void schemaChange(ChangeEvent changeEvent)
    {
        String schemaName = changeEvent.getSchemaName();

        if (null != myBuilder && schemaList.contains(schemaName))
        {
            initVariables();
        }
    }
}, "SCHEMA1");

服务使用上面的一段代码来注册多个值的侦听器“SCHMA1”、“SCHMA1”、“SCHMA3”...我计划在各种捆绑包中重用此服务。但是我想只听ScheMA1的变化,而不是全部。

@参考(name="ServiceListener",策略=Reource策略。动态,基数=参考基数。MANDATORY_UNARY,bind="bind",unbind="unbind",引用接口=ServiceListener.class)私有原子引用myServiceListener=new原子引用

如果我试图在另一个服务中使用它,那么没有规定将值传递给服务,以便只监听特定的模式更改,这样服务就可以通过只传递要监听的模式列表而不是所有模式列表来在我的捆绑包中重新启动...因为一旦服务在使用类(组件)中被正确绑定,激活方法将被调用。OSGi中是否有实现此功能的规定?

共有2个答案

方博
2023-03-14

一种方法是为每个模式创建一个服务。您可以通过提供模式名称作为配置值并使用多个配置来实现这一点。然后,每个这样的服务还将此配置参数作为服务属性。因此,客户端可以筛选架构属性。

如果您不想使用这些配置,那么您可以创建一个提供工厂的服务。然后,每个客户端将绑定工厂,并通过在工厂的创建方法中提供模式名称来创建实例。

周越泽
2023-03-14

您几乎没有描述您的应用程序实际上是如何工作的,这使得这个问题很难回答。

从您共享的代码来看,您似乎遵循了一个非常糟糕的模式。监听器模式是许多同步问题和内存泄漏的根源,当您使用OSGi时,应该首选白板模式。

白板图案很简单。您不是让每个侦听器查找服务并注册它,而是颠倒模型。事件的来源(在本例中是模式更改)查找在OSGi服务注册表中注册的侦听器服务。这样监听器就很容易编写和过滤,并且没有混乱和容易出错的添加/删除监听器逻辑到代码中。

更好的模型应该使用服务属性来选择特定的模式,并且看起来像这样(使用标准的OSGi注释)。

监听器1(监听ScheMA1的更改)

@Component(
    property="schemaName=SCHEMA1")
public class MyListener implements ChangeListener {
    // Your implementation in here
}

侦听器2(侦听对SCHEMA1、SCHEMA2和SCHEMA3的更改)

@Component(
    property={"schemaName=SCHEMA1",
              "schemaName=SCHEMA2",
              "schemaName=SCHEMA3"})
public class MyListener implements ChangeListener {
    // Your implementation in here
}

Schema1的事件源示例:

@Component
public class MyListener implements ChangeListener {

    @Reference(policy=DYNAMIC, target="(schemaName=SCHEMA1)")
    private final List<ChangeListener> listeners = new CopyOnWriteArrayList<>();

    private void onSchemaChange(ChangeEvent event) {
        listeners.forEach(l -> l.schemaChange(event);
    }

    // Rest of your implementation in here
}
 类似资料:
  • 我正在使用注释处理来生成一些类...我有两个模块,处理器本身和使用它的“客户端”模块。我想通过客户端向处理器传递一个参数,我可以这样做 如何在处理器端检索此参数?

  • 问题内容: 方法context.getBean(name,user)的文档说 允许指定显式构造函数参数/工厂方法参数 但是无论我做什么(尝试一切),使用最合理的设置在初始化期间加载Bean时都会得到以下信息: 注释说可以做到的,但是如果您在该bean的xml定义中指定构造函数参数,则失败。 问题答案: 在javadoc中说: args-在使用静态工厂方法的显式参数创建原型时使用的参数。 因此,be

  • 假设我有一个带有属性的注释: 我想创建一个包含多个元注释的复合注释,包括一个带有属性的注释 有没有一种方法可以将复合注释的属性传递给其中一个元注释? 例如,类似这样的东西: 这相当于,但比 谢谢! PS为我对示例注释的错误选择表示歉意-我没有javax。注射@记住命名注释,只是一些具有属性的任意注释。 谢谢大家的回答/评论。 这显然是不可能的。然而,碰巧我的案例有一个简单的解决方法,我将与大家分享

  • 问题内容: 我希望能够在运行selenium时将参数传递给google chrome。我怎样才能做到这一点?运行selenium时,我使用Java命令Java -jar selenium.jar 如何将诸如no-sandbox,ignore-gpu-blacklist,enable-webgl之类的参数传递给google chrome可执行文件。谢谢 我正在用守夜人 问题答案: 您可以使用启动驱动

  • 问题内容: 我从Eclipse项目构建了可运行的JAR,该项目处理给定的XML文件并提取纯文本。但是,此版本要求文件在代码中进行硬编码。 有没有办法做这样的事情 并让jar在xml文件上执行? 我已经四处查看,给出的所有示例都与在命令行上编译JAR有关,而没有一个处理传入参数。 问题答案: 为什么不 ? 只需修改您的参数即可接收论据并对其进行操作。 在命令行中指定完整路径。

  • 我正在尝试创建自己的复合验证注释来验证字符串——到目前为止,它由注释@NotNull、@NotBlank和@Size组成 但是,我不想让它们保持默认值,而是希望能够传入一个参数值,例如,如果我执行@ValidString(min=1,max=50),那么@Size注释可以读取这些值——这可能吗? 我的约束-