【问题标题】:Camel dynamically build processor bean callCamel动态构建处理器bean调用
【发布时间】:2018-02-09 19:39:06
【问题描述】:

下面是我为一个主题设置的 bean 示例。请记住,有多个 bean...每个消息类型一个

通过为每个消息类型设置一个路由,我已经能够成功接收和处理我的所有消息类型,但我想简化上下文文件,因此我只需要一个接收我所有主题的路由。

这是我的路线设置的样子...

    <route id="Netty7001Route">
       <from uri="netty4:tcp://192.168.200.3:7001…"/>
       <to uri=”seda:ProcessRoute”/>
    </route>

    <route id=”ProcessRoute”/>
      <from uri=”seda:ProcessRoute”/>
           <setHeader headerName="LOGMESSAGE"><simple>A10::Entering endpoint for track message ${in.header.MSGNAME} via netty4</simple></setHeader>
           <to uri="log:messageLogger?level=ERROR"/>
           <setHeader headerName="LOGMESSAGE"><simple>A11::Leaving endpoint for track message ${in.header.MSGNAME}</simple></setHeader>
           <to uri="log:messageLogger?level=ERROR"/>
           <setHeader headerName="LOGMESSAGE"><constant>A14::Entering Mediation</constant></setHeader>
           <to uri="log:messageLogger?level=ERROR"/>
           **<process ref="DDS_C2_NewSystemReferencePointMediationBean"/>**
       <setHeader headerName="MSGNAME"><constant>C2_TM_NewSystemReferencePoint</constant></setHeader>
       <setHeader headerName="MSGTYPE"><constant>C2_NewSystemReferencePoint</constant></setHeader>
           <setHeader headerName="LOGMESSAGE"><constant>A15::Leaving Mediation</constant></setHeader>
           <to uri="log:messageLogger?level=ERROR"/>
           <setHeader headerName="LOGMESSAGE"><constant>A17::Sending message to DDS domain 4</constant></setHeader>   
           <to uri="log:messageLogger?level=ERROR"/>
       <to uri="dds://4/C2_TM_NewSystemReferencePoint?typeName=C2_NewSystemReferencePoint"/>
    </route>

所以,上面的 process ref= 行是我想要动态的,因为在我查看标题中的 MSGNAME 之前,我不知道要调用哪个 bean 处理器。我尝试使用收件人列表失败,因为它们不是端点,而是处理器 bean,我尝试仅使用 ref:DDS_C2_{$in.header.MSGNAME}MediationBean,但骆驼不会启动并抱怨这里的简单标签.有没有办法在骆驼弹簧配置中做到这一点?

我尝试了一种解决方法,方法是使用检查 MSGNAME 然后调用相应的处理器 bean 的标记,但我需要为每种消息类型设置条件。这很有效,但与每个主题都有一条路线相比,效率极低。

我考虑过编写一个处理器,它会在 java 代码中调用适当的 bean 处理器,但我不确定这是否是满足我需要的正确方法,以及它是否比使用标记。

感谢您的帮助。

【问题讨论】:

  • 澄清一下,我说的是代码中的进程 ref= 标签。此外,为我编写一个处理器来确定 bean 调用将在消息类型更改或添加时强制更新代码,因此我需要基于 spring 的解决方案。
  • “我考虑过只写一个处理器,它会在 java 代码中调用适当的 bean 处理器”我相信这将是一种方法(不管安全问题,提供一个类来调用 http 标头..) 直接和点在启动时进行评估,因此您不能动态提供“ref”
  • 你为什么不使用choice().when(header==''whatever") 然后调用你的进程?注意我说的是使用choice/when 功能。 xml dsl。
  • 我尝试使用选择/何时,但我有 96 种不同的消息类型,并且在测试期间性能比我为每个主题有一个路由时慢得多。

标签: spring apache-camel javabeans processor


【解决方案1】:

最好的方法是创建一个带有 ProcessorEndpoint 的新组件,如 here 所述。

工作示例(带处理器)

  1. 创建您的自定义组件:

    package com.mgyongyosi.sample.component;
    
    // imports
    
    public class SpecifiedProcessor extends DefaultComponent {
    
    @Override
    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
        Object registryObj = getCamelContext().getRegistry().lookupByName(remaining);
    
        if(!(registryObj instanceof Processor))
            throw new IllegalArgumentException("The Processor with the specified name was not found in the Registry.");
    
        return new ProcessorEndpoint(uri, this, (Processor)registryObj);
    }
    
  2. 通过在 META-INF/services/org/apache/camel/component 目录中创建一个名为 specified-processor 的文件(这将是组件的 uri 方案)来注册您的组件,其中包含以下内容 (full documentation):

    class=com.mgyongyosi.sample.component.SpecifiedProcessor
    
  3. Java DSL 的示例用法:

    from("timer:helloworld?period=5000")
            .setHeader("MSGNAME", constant("NewSystemReferencePoint"))
            .toD("specified-processor://DDS_C2_${in.header.MSGNAME}MediationBean")
            .log("${body}");
    

在 XML 中:

<toD uri="specified-processor://DDS_C2_${in.header.MSGNAME}MediationBean"/>

如果是豆类

Java DSL:.toD("bean:DDS_C2_${in.header.MSGNAME}MediationBean")

XML:&lt;toD uri="bean:DDS_C2_${in.header.MSGNAME}MediationBean"/&gt;

【讨论】:

  • 问题在于我的 MediationBean 不是处理器。是否还有一种方法可以通过将它们包装在 ProcessorEndpoint 中来调用这些 MediationBean,就像您在此处概述的那样?
  • 使用.toD("bean:DDS_C2_${in.header.MSGNAME}MediationBean")&lt;toD uri="bean:DDS_C2_${in.header.MSGNAME}MediationBean"/&gt;
  • 太棒了!谢谢你,先生。只是不知道如何正确调用它。
  • 如果 bean 名称包含“dot”,这个“bean:”表达式会起作用吗?我也有类似的情况,有什么出路吗?
猜你喜欢
  • 2011-08-29
  • 1970-01-01
  • 2019-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-22
  • 1970-01-01
相关资源
最近更新 更多