【问题标题】:Custom Spring Scope not working for Message Channel自定义 Spring 范围不适用于消息通道
【发布时间】:2014-04-20 09:45:45
【问题描述】:

在 spring 集成中,我正在尝试创建一个具有自定义范围的直接消息通道,如下所示

  ...
  <int:channel id="myChannel" scope="validCustomScope" />
  <int:service-activator ref="validSericeReference_WithSameValidCustomScope" method="handleMessage" input-channel="myChannel"/>
  ...

但是,我遇到了异常..

org.springframework.integration.MessageDeliveryException: Dispatcher has no subscribers for channel 

注意:此自定义范围适用于其他 bean。 这个问题类似于here 讨论的问题,但没有解决方案。如果有人可以帮助解决这个问题,那将是一个巨大的帮助。

【问题讨论】:

    标签: java spring message-queue spring-integration


    【解决方案1】:

    服务激活器只会订阅其中一个实例。其他人会抛出Dispatcher has no subscribers

    您的自定义范围需要弄清楚如何在服务激活器为start() ed 时为每个实例传播订阅(服务激活器的MessageHandler),然后将其传播到创建的任何新实例after 端点已启动。

    可能不平凡。

    就是这么说的。我不清楚作用域通道向非作用域服务发送消息的好处。

    也许如果你解释一下你想用自定义范围做什么,可能会有一个通用的解决方案,但我猜它需要在自定义范围中使用一些棘手的代码。

    【讨论】:

    • 谢谢 Gary -- 我们希望一个范围频道仅向完全相同范围内的服务发送消息。有办法强制吗?
    • 是的;创建一个单独的子上下文(带有通道、服务)并使用动态路由器路由到适当的通道。有关如何执行此操作的示例,请参阅动态 FTP 示例。 github.com/spring-projects/spring-integration-samples/tree/…
    • 感谢您的示例参考。服务激活器可以不订阅相同范围的频道吗?与尝试编写代码以在运行时动态路由消息相比,这将是一种更自然的配置。 能以某种方式提供帮助吗?我们甚至尝试使用docs.spring.io/spring-integration/reference/html/… 的“Scoped Channel”部分中指定的通道的线程范围,但导致相同的“Dispatcher 没有通道订阅者”异常。
    • 不,框架只是没有设置为理解该级别的范围通道。当应用程序上下文启动消费者时,会发生通道订阅者连接。就其本质而言,范围通道可以在上下文启动后来来去去。文档中的ThreadLocal 范围是一种特殊情况,仅适用于QueueChannel。在您的自定义范围内,您可以订阅一个新的处理程序。让您的处理程序实现 MessageHandler 并在您的自定义范围中声明它 - 从上下文中获取一个新的处理程序实例并在您创建新频道时订阅它。
    • 谢谢 Gary -- 我们正在处理路由器选项。但是,是否可以在 Spring Integration 中打开一张票,以便将来允许相同的 Scoped Channels 和 Services @autowired,而无需让该路由器检测正确的服务的开销?能够做到这一点有一个巨大的优势。再次感谢。
    【解决方案2】:

    这很好地解释了为什么会遇到“调度程序没有订阅者”异常。我们将在多租户环境中使用 Spring Integration,以便每个租户使用他/她自己的通道和服务激活器。我们已将相同的范围应用于服务激活器 bean 定义。对此有何建议?

    <bean id="validSericeReference" class="ValidSericeClass" scope="validCustomScope"/> 
    

    【讨论】:

    • 为每个租户(带有通道、服务)创建一个单独的子上下文,并使用动态路由器路由到适当的通道。有关如何执行此操作的示例,请参阅动态 FTP 示例。 github.com/spring-projects/spring-integration-samples/tree/…
    • 如果您的ValidServiceClass 实现MessageHandler(可能是AbstractReplyProducingMessageHandler 的子类),您可以在创建新频道时订阅一个新频道 - 但您的范围必须完成这项工作。
    • 在我的消息传递上下文中,有很多特定于租户的通道和服务处理程序,我必须为所有这些设置范围。在这种情况下,我应该为我的客户范围类中的每个通道订阅每个消息处理程序吗?我可以在 XML 配置中声明它们的任何通用方式?
    • 对多租户环境中的可轮询频道有什么建议吗?谢谢。
    • 无论通道类型如何,您都需要动态运行时组件接线。该框架假定静态连接,在上下文启动时建立。您可以使用自定义命名空间解析器做一些事情;我能想到的唯一使用标准组件的解决方案是使用动态路由器并将每个租户放在自己的子配置中。
    猜你喜欢
    • 2018-08-24
    • 1970-01-01
    • 2021-12-19
    • 2020-02-07
    • 2014-07-08
    • 1970-01-01
    • 2013-03-03
    • 2015-05-01
    • 2016-04-25
    相关资源
    最近更新 更多