根据消息 body 或 header 中的 属性 动态加载 Camel 处理器

Dynamically Loading Camel Processor depending on a property in message body or header

我正在寻找一种解决方案,通过在运行时根据消息 header 或 body 上的某些属性动态决定的处理器路由消息。

假设我有两个消息处理器(例如:Type1RequestProcessorType2RequestProcessor),如下所述。

我想做的是执行 Type1RequestProcessorType2RequestProcessor 在消息 header 或 body 中使用 属性 动态决定。(在这里我不想为每个处理器类型创建多个路由器。)

我试过如下所述(在 header 中传递 typeId)。但它显然给出了下面的错误 No bean could be found in the registry for: ${header.messageId}RequestProcessor of type: org.apache.camel.Processor.

HTTPRouter.java

import javax.enterprise.context.ApplicationScoped;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.cdi.ContextName;

@ApplicationScoped
@ContextName("camel-cdi-context")
public class HTTPRouter extends RouteBuilder {

    @Override
    public void configure() throws Exception {

        from("direct:oneRouter")
        .process("${header.typeId}RequestProcessor")
        .to("direct:anotherRouter");
    }
}

错误:

org.apache.camel.FailedToCreateRouteException: Failed to create route route19 at: >>> process[ref:${header.messageId}RequestProcessor] <<< in route: Route(route19)[[From[direct:oneRouter]] -> [process[ref:${he... because of No bean could be found in the registry for: ${header.messageId}RequestProcessor of type: org.apache.camel.Processor
    at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:1298)
    at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:204)
    at org.apache.camel.impl.DefaultCamelContext.startRoute(DefaultCamelContext.java:1087)
    at org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:3540)
    at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:3271)
    at org.apache.camel.impl.DefaultCamelContext.access[=14=]0(DefaultCamelContext.java:202)

我也尝试使用 bean 组件,但结果是一样的。

有人可以帮忙吗? 如何动态加载处理器?

Type1RequestProcessor.java

import org.apache.camel.Exchange;
import org.apache.camel.Processor;

public class Type1RequestProcessor implements Processor {

    public void process(Exchange exchange) throws Exception {

        // Do Type1 process implementation

    }

}

Type2RequestProcessor.java

import org.apache.camel.Exchange;
import org.apache.camel.Processor;

public class Type2RequestProcessor implements Processor {

    public void process(Exchange exchange) throws Exception {

        // Do Type2 process implementation

    }

}

注意: 我有计划 B 在路由器本身的处理方法中动态加载这些实现(匿名内部 Class)。但我仍在寻找这个,因为它非常适合我正在寻找的东西。

动态表达式语言不能在进程方法内部使用,但您可以使用 @Named 注释您的处理器,使其在 CDI 注册表中可用。然后使用 .toD(bean:${header.typeId}RequestProcessor) 或直接使用 .toD(${header.typeId}RequestProcessor).

通过 bean 组件调用它

请注意命名 bean 名称默认转换为 class 驼峰命名法。您可以使用 @Named("Type1RequestProcessor").

自定义此行为