如何在 Spring XML 中为 Apache Camel 的灵活聚合策略设置“选择”表达式?

Jac*_*son 4 xml apache spring apache-camel

我正在尝试使用 Apache Camel 2.14 在 Spring XML 中配置 Apache Camel 路由。该路线将涉及一个<aggregator>或一个<enrich>/ <pollEnrich>;我对 Camel 的使用经验还不够,不知道哪个 EIP 最有用。不管怎样,我都需要一个aggregationStrategy. 我的最终目标是为希望在 XML 中配置路由的客户端创建 Camel 路由。

通过在互联网上搜索,我了解到存在一个名为 的 Camel 类FlexibleAggregationStrategy。我发现的东西声称,并且我引用,“它允许您快速创建一个 AggregationStrategy,能够以零 Java 代码执行最典型的聚合任务。” 这对我来说听起来很有用,因为我们希望尽可能多地使用 XML 进行配置。因此,最好避免AggregationStrategy用 Java 编写自己的代码。问题是,我不知道如何使用FlexibleAggregationStrategy.

据我所知,它FlexibleAggregationStrategy使用被Expression调用的消息从消息中挑选元素进行聚合pickExpression,并过滤掉与Predicate conditionPredicate. 因此,我假设我需要一种方法在 Spring XML 中设置这些值。不幸的是,我无法让以下代码块工作:

属性名称设置为pickExpression,值作为元素:

<bean id="FlexibleAggregationStrategy"
    class="org.apache.camel.util.toolbox.FlexibleAggregationStrategy">
    <property name="pickExpression">
        <xpath>
            //ID
        </xpath>
    </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

属性名称设置为pick,值作为元素:

<bean id="FlexibleAggregationStrategy"
    class="org.apache.camel.util.toolbox.FlexibleAggregationStrategy">
    <property name="pick">
        <xpath>
            //ID
        </xpath>
    </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

属性名称设置为pickExpression,值设置为属性:

<bean id="FlexibleAggregationStrategy"
    class="org.apache.camel.util.toolbox.FlexibleAggregationStrategy">
    <property name="pickExpression" value="&lt;xpath&gt;//ID&lt;/xpath&gt;"/>
</bean>
Run Code Online (Sandbox Code Playgroud)

属性名称设置为pick,值设置为属性:

<bean id="FlexibleAggregationStrategy"
    class="org.apache.camel.util.toolbox.FlexibleAggregationStrategy">
    <property name="pick" value="&lt;xpath&gt;//ID&lt;/xpath&gt;"/>
</bean>
Run Code Online (Sandbox Code Playgroud)

每次,我都会收到一条错误消息,抱怨无法找到具有我指定名称的属性描述符。pick我尝试这两种方法的原因pickExpression是,在FlexibleAggregationStrategy的源代码中,类中保存pick表达式的变量被命名为pickExpression,但设置它的方法只是被调用pick()

我对 Spring XML 没有完全的理解,但据我所知,使用标签<property>设置变量值需要 bean 具有该变量的 getter 和 setter。由于FlexibleAggregationStrategy没有 getter 和 setter pickExpression,所以我无论如何都遵循错误的方法。但是,如果我正确读取标记的 XML 架构定义<bean>,则将信息发送到 bean 的唯一方法是使用<property>标记或构造函数参数。由于FlexibleAggregationStrategy没有设置 的构造函数pickExpression,我还没有找到一种FlexibleAggregationStrategy无需编写 Java 代码即可配置 的方法。

我发现了对“方法注入”的引用,它可能允许我配置FlexibleAggregationStrategy. 然而,我发现的唯一说明涉及用 Java 编写 bean。因此,该技术还涉及编写 Java 代码;另外,似乎只写我自己的会更快更直接AggregationStrategy

截至目前,记录该模式的新旧 Apache Camel Wiki 页面都根本<aggregator>没有提及。FlexibleAggregationStrategy

我尝试在 Google 上搜索该术语FlexibleAggregationStrategy,看看是否有人编写过使用FlexibleAggregationStrategy. 截至目前,我获得的前两个 Google 结果是该类自动生成的 Javadoc FlexibleAggregationStrategy。第三个结果是我上面链接的 github 托管的源代码。第四个结果是我发布的关于该主题的另一个问题;这个问题已关闭,因为我不明白如何编写正确的 StackOverflow 问题。第五个结果是 grepcode.com 上托管的源代码。第六个结果是我不理解的接口的 Javadoc。第七个结果是别人在grokbase.com上问的一个问题;这个问题没有答案。第八个结果是其他人在 qnalist.com 上提出的问题,但也没有答案。第九个结果似乎来自涉及提交该类源代码的邮件列表FlexibleAggregationStrategy。第十个结果是 grokbase 发布到 osdir.com 的问题。类似的搜索返回的结果大多相同;我发现其他新结果同样没有帮助。我认为,如果有人编写了一个很好的使用指南FlexibleAggregationStrategy,它就会出现在这些搜索中。

有谁用过的FlexibleAggregationStrategy可以告诉我怎么设置吗pickExpressionconditionPredicate以便我可以使用 a FlexibleAggregationStrategy?如果您知道我需要配置它的任何其他信息,或者围绕它的任何其他常见陷阱,我们也将不胜感激。

感谢您的时间。

pim*_*ttc 5

Spring 的 XML 格式并不是真正适合流畅的构建器,但您可以做到。例如,要复制此内容:

delegateStrategy = new FlexibleAggregationStrategy<Object>()
        .storeInBody()
        .accumulateInCollection(ArrayList.class)
        .pick(new SimpleExpression("${header[CamelFileName]}"));
Run Code Online (Sandbox Code Playgroud)

需要这个 XML:

<bean id="_flexible0" class="org.apache.camel.util.toolbox.FlexibleAggregationStrategy"/>
<bean id="_flexible1" factory-bean="_flexible0" factory-method="storeInBody" />
<bean id="_flexible2" factory-bean="_flexible1" factory-method="accumulateInCollection">
  <constructor-arg value="java.util.ArrayList" />
</bean>
<bean id="fileNameListStrategy" factory-bean="_flexible2" factory-method="pick">
  <constructor-arg>
    <bean class="org.apache.camel.model.language.SimpleExpression">
      <constructor-arg type="java.lang.String" value="${header[CamelFileName]}" />
    </bean>
  </constructor-arg>
</bean>
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它不是很简洁,并且需要创建许多中间 bean,但这是可能的。

但是,如果您不限于零个自定义 Java,您可以创建自己的 AggregationStrategy,将其委托给FlexibleAggregationStrategy 并在 XML 中使用它。

Java部分:

public class FileNameListAggregationStrategy implements AggregationStrategy {

    private CompletionAwareAggregationStrategy delegateStrategy;

    public FileNameListAggregationStrategy() {
        delegateStrategy = new FlexibleAggregationStrategy<Object>()
                .storeInBody()
                .accumulateInCollection(ArrayList.class)
                .pick(new SimpleExpression("${header[CamelFileName]}"));
    }

    @Override
    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
        return delegateStrategy.aggregate(oldExchange, newExchange);
    }

}
Run Code Online (Sandbox Code Playgroud)

XML部分:

<bean id="fileNameListStrategy" class="org.example.camel.FileNameListStrategy"/>
Run Code Online (Sandbox Code Playgroud)