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

Spring集成:动态注册IntegrationFlow的刷新/重新加载

冯风史
2023-03-14

我从“dynconfigflows”-目录中加载xml配置文件,然后动态创建IntegrationFlow。
每个xml文件一个IntegrationFlow。如果配置文件已编辑,则应更新IntegrationFlow。IntegrationFlow的注册id被设置为配置文件名。
,因此当前的流应该平稳地停止(没有更多的输入消息和当前处理的消息应该完成)。在此之后,应该删除它,并注册流的更新版本。
现在的问题是:
a)在下面的JUnit测试中,如果我没有调用Registration.remove(ID),我可以用相同的ID注册两个流;这被认为是行为吗?ID不应该是唯一的吗?
b)在调用remove(...)之后,我试图向removed InputChannel再发送一条消息。我得到了一个错误,但仍然可以看到工作的removed流的日志输出。

我应该如何实现动态IntegrationFlow的刷新/重新加载功能?

@Test
public void testRegisterUnregister() {
    final String FLOW_ID = "regFlow";
    Flux<Message<?>> messageFlux = Flux.just("1,2,3,4").map(v -> v.split(",")).flatMapIterable(Arrays::asList)
            .map(Integer::parseInt).map(GenericMessage<Integer>::new);

    QueueChannel resultChannel = new QueueChannel();

    IntegrationFlow regFlow = createFlow("first", messageFlux, resultChannel);

    IntegrationFlowRegistration register1 = this.flowContext.registration(regFlow).id(FLOW_ID).register();
    final String FIRST_ID = register1.getId();
    System.out.println("!!!!!!!!!!!!!!!! register flow: "+FIRST_ID);
    // validate incoming of 4 integers
    assertThat(resultChannel.getQueueSize()).as("queueSize").isEqualTo(4);
    // save reference to first InputChannel
    MessageChannel input1 = register1.getInputChannel();

    // stop and remove first flow
    register1.stop();
    this.flowContext.remove(FIRST_ID);
    // wait for the case if flows shutdown needs some time
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    // create second flow
    regFlow = createFlow("second", messageFlux, resultChannel);
    IntegrationFlowRegistration register2 = this.flowContext.registration(regFlow).id(FLOW_ID).register();
    System.out.println("!!!!!!!!!!!!!!!! register flow: "+register2.getId());
    // send extra message to the second flow
    register2.getInputChannel().send(MessageBuilder.withPayload("!!!!!!!!!!! new registered flow message").build());
    try {
        // send extra message to the first flow. It should fail because first flow is removed.
        // It fails but we still see "!!!!!!!!!!! new registered flow message" from first flow. It should't happen!
        input1.send(MessageBuilder.withPayload("!!!!!!!!!!! new registered flow message").build());
        Assert.fail("we should get an exception because first flow is removed");
    } catch (MessageDeliveryException e) {
        e.printStackTrace();
    }

    assertThat(resultChannel.getQueueSize()).as("queueSize=2 x 4 + 1").isEqualTo(9);
}

private IntegrationFlow createFlow(String markerText, Flux<Message<?>> messageFlux, QueueChannel resultChannel) {
    return IntegrationFlows
            .from(messageFlux)
            .log(l -> "!!!!!!!!!!!!!!!!!!!!!!! "+markerText+"="+l)
            .channel(resultChannel)
            .get();
}

共有1个答案

丰胤运
2023-03-14

第一个问题肯定是一个bug:https://jira.spring.io/browse/int-4413。

我们可以在应用程序上下文中重写现有bean,因为默认情况下允许:

if (oldBeanDefinition != null) {
        if (!isAllowBeanDefinitionOverriding()) {
            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                    "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
                    "': There is already [" + oldBeanDefinition + "] bound.");
        }

但是,在integrationflowcontext中。我们将在提到的JIRA中拒绝这种状态。

 类似资料:
  • 我想在注销后刷新/重新加载页面(屏幕上的消息在5秒钟内可见)。当前代码不会刷新它,所以我仍然在标题中看到用户名,而不是像登录按钮这样的东西。 我已经检查了这篇文章,但没有什么变化。

  • 问题内容: 这是一个非常基本的问题-但我无法通过在线搜索找到答案。 我正在使用python控制ArcGIS,并且有一个简单的python脚本,该脚本调用了一些预先编写的代码。 但是,当我对预写代码进行更改时,它似乎没有导致任何更改。我导入了此模块,并尝试刷新它,但是没有任何反应。 我什至将它调用的文件移到了另一个位置,脚本仍然可以正常工作。昨天我做的一件事是我将所有python文件都添加到sys路

  • 我们看到,前几个流需要大约100ms来注册,当它达到300时,注册每个流需要7秒。这些流本质上是相同的(它们只是记录一条信息消息并返回)。 如果能帮助解决这个问题,我们将不胜感激。 java(动态(手动)注册流的自动配置类) java(所有集成流用于将请求委托给负责业务逻辑实现的Coreflow的公共类) java(处理业务逻辑的类)

  • 问题内容: 如何在不重新启动servlet容器的情况下刷新Spring配置文件? 我正在寻找JRebel以外的解决方案。 问题答案: 对于那些最近在这上面绊脚石的人来说,解决此问题的当前和现代方法是使用Spring Boot的Cloud Config。 只需添加注释你刷新豆类和你的主/配置。 因此,例如,以下Controller类: 在Spring Boot Actuator上(通过HTTP端点或

  • 问题内容: 我正在尝试实现一些功能,即单击屏幕上的按钮将导致我的[QuerydataTable刷新(因为自创建dataTable以来服务器端数据源可能已更改)。 这是我所拥有的: 但是当我运行它时,它什么也没做。单击按钮时刷新dataTable的正确方法是什么?提前致谢! 问题答案: 您可以尝试以下方法:

  • 问题内容: 我正在使用Java进行项目,因此需要在单击特定按钮后重新加载整个程序。这该怎么做? 问题答案: 尝试 如果仍然无法使用,请在完成上述步骤后尝试