对于最新稳定版本,请使用 Spring Integration 7.0.0spring-doc.cadn.net.cn

Filter

消息过滤器用于判断消息应根据某些条件传递或放弃,比如消息头值或消息内容本身。 因此,消息过滤器类似于路由器,不同之处在于,对于从过滤输入通道接收到的每条消息,该消息可能被发送到过滤器的输出通道,也可能不会。 与路由器不同,它不会决定将消息发送到哪个信道,只决定是否发送消息。spring-doc.cadn.net.cn

正如我们本节后面所述,Filter还支持丢弃通道。 在某些情况下,它可以作为一个非常简单的路由器(或“交换机”),基于布尔条件。

在 Spring Integration 中,你可以将消息过滤器配置为消息端点,委派给消息选择器接口。 该界面本身相当简单,如下列表所示:spring-doc.cadn.net.cn

public interface MessageSelector {

    boolean accept(Message<?> message);

}

消息过滤构造函数接受选择器实例,如下示例所示:spring-doc.cadn.net.cn

MessageFilter filter = new MessageFilter(someSelector);

使用 Java、Groovy 和 Kotlin DSL 配置过滤器

IntegrationFlowBuilderJava DSL(也作为Groovy和Kotlin DSL的基础)提供的filter()算子。 这消息选择器上述抽象可以作为 Lambda 在filter()定义:spring-doc.cadn.net.cn

@Bean
public IntegrationFlow someFlow() {
    return f -> f
              .<String>filter((payload) -> !"junk".equals(payload));
}
@Bean
fun someFlow() =
    integrationFlow {
        filter<String> { it != "junk" }
    }
@Bean
someFlow() {
    integrationFlow {
        filter String, { it != 'junk' }
    }
}

有关DSL的更多信息,请参阅相关章节:spring-doc.cadn.net.cn

使用 XML 配置过滤器

结合命名空间和 SpEL,你可以用很少的 Java 代码配置强大的过滤器。spring-doc.cadn.net.cn

你可以使用<Filter>元素用于创建消息选择端点。 此外输入通道输出通道属性,它需要一个裁判属性。 这裁判可以指向消息选择器实现方式,如下示例所示:spring-doc.cadn.net.cn

<int:filter input-channel="input" ref="selector" output-channel="output"/>

<bean id="selector" class="example.MessageSelectorImpl"/>

或者,你也可以添加方法属性。 在这种情况下,裁判属性可以指代任何对象。 引用的方法可能期望消息输入消息的类型或有效载荷类型。 该方法必须返回一个布尔值。 如果方法返回“true”,消息会发送到输出信道。 以下示例展示了如何配置使用以下条件的过滤器方法属性:spring-doc.cadn.net.cn

<int:filter input-channel="input" output-channel="output"
    ref="exampleObject" method="someBooleanReturningMethod"/>

<bean id="exampleObject" class="example.SomeObject"/>

如果选择器或自适应的POJO方法返回false,有几个设置控制被拒绝消息的处理。 默认情况下(如前例配置)拒绝消息会被静默丢弃。 如果拒绝结果应导致错误,则设拒绝时抛出异常归属为true,如下示例所示:spring-doc.cadn.net.cn

<int:filter input-channel="input" ref="selector"
    output-channel="output" throw-exception-on-rejection="true"/>

如果你希望被拒绝的消息被路由到特定信道,请提供该引用作为丢弃通道,如下示例所示:spring-doc.cadn.net.cn

<int:filter input-channel="input" ref="selector"
    output-channel="output" discard-channel="rejectedMessages"/>

如果throwExceptionOnRejection == falsediscardChannel提供时,消息会被静默投放,并且o.s.i.filter.MessageFilter实例只会发出警告日志消息(从版本6.1开始),关于该被丢弃消息。 如果在日志中没有任何预警地发布消息,一个零通道可以配置为discardChannel在过滤器上。 该框架的目标是默认不完全静默,如果需要设置显式选项,则不要求设置。spring-doc.cadn.net.cn

消息过滤器通常与发布-订阅频道配合使用。 许多过滤端点可能订阅同一个通道,它们决定是否将消息传递给下一个端点,该端点可以是任何支持的类型(如服务激活器)。 这为使用拥有单点对点输入通道和多个输出通道的消息路由器提供了一种被动替代方案。

我们建议使用裁判如果自定义Filter实现在其他地方被引用,属性<Filter>定义。 然而,如果自定义Filter的实现作用域仅为单一<Filter>元素,你应该提供一个内部的豆子定义,如下示例所示:spring-doc.cadn.net.cn

<int:filter method="someMethod" input-channel="inChannel" output-channel="outChannel">
  <beans:bean class="org.foo.MyCustomFilter"/>
</filter>
同时使用裁判属性和内部处理程序定义在同一个<Filter>不允许配置,因为这会产生歧义条件并抛出异常。
如果裁判属性指代扩展的豆子消息过滤(例如框架本身提供的Filter),该配置通过直接将输出通道注入滤波豆进行优化。 在这种情况下,每一个裁判必须是独立的豆子实例(或原型-有瞄准镜的豆子)或使用内层<豆/>配置类型。 然而,这种优化仅适用于你在筛选 XML 定义中没有提供任何特定过滤器属性的情况。 如果你无意中引用了多个 Beans 中的同一个消息处理程序,就会出现配置异常。

随着 SpEL 支持的引入,Spring Integration 增加了表达属性映射到滤波元件。 它可以完全避免简单过滤器的 Java,如下示例所示:spring-doc.cadn.net.cn

<int:filter input-channel="input" expression="payload.equals('nonsense')"/>

作为表达属性值传递的字符串作为 SpEL 表达式被评估,消息可在评估上下文中获得。 如果你必须在应用上下文的范围内包含表达式的结果,你可以使用SpEL参考文档中定义的符号,如下示例所示:#{}spring-doc.cadn.net.cn

<int:filter input-channel="input"
            expression="payload.matches(#{filterPatterns.nonsensePattern})"/>

如果表达式本身需要动态,可以使用“表达式”子元素。 这为通过密钥解析表达式提供了一层间接的ExpressionSource. 这是一个你可以直接实现的策略界面,或者你可以依赖 Spring Integration 中提供的版本,它会从“资源包”加载表达式,并在给定秒后检查修改情况。 所有这些都在下面的配置示例中得到展示,如果底层文件被修改,表达式可以在一分钟内重新加载:spring-doc.cadn.net.cn

<int:filter input-channel="input" output-channel="output">
    <int:expression key="filterPatterns.example" source="myExpressions"/>
</int:filter>

<beans:bean id="myExpressions"
    class="o.s.i.expression.ReloadableResourceBundleExpressionSource">
    <beans:property name="basename" value="config/integration/expressions"/>
    <beans:property name="cacheSeconds" value="60"/>
</beans:bean>

如果ExpressionSource豆子被命名表达来源,你无需在<表情>元素。 然而,在前面的例子中,我们为了完整性而展示它。spring-doc.cadn.net.cn

“config/integration/expressions.properties”文件(或任何带有区域扩展的更具体版本,需要以典型的资源包加载方式解析)可以包含键值对,如下示例所示:spring-doc.cadn.net.cn

filterPatterns.example=payload > 100
所有这些例子都使用表达作为属性或子元素也可以应用于转换器、路由器、分配器、服务激活器和头部丰富器元素中。 给定组件类型的语义和角色会影响评估结果的解释,就像方法调用的返回值被解释一样。 例如,表达式可以返回字符串,这些字符串将被路由器组件视为消息通道名称。 然而,作为根对象对消息进行表达式评估以及如果以“@”作为前缀进行解析豆子名的底层功能,在Spring Integration中所有核心EIP组件中都是一致的。

带注释的过滤器配置

以下示例展示了如何通过注释配置过滤器:spring-doc.cadn.net.cn

public class PetFilter {
    ...
    @Filter  (1)
    public boolean dogsOnly(String input) {
        ...
    }
}
1 注释说明该方法将用作Filter。 如果该类被用作过滤器,必须指定它。

XML 元素提供的所有配置选项也适用于@Filter注解。spring-doc.cadn.net.cn

过滤器可以明确引用 XML 或@MessageEndpoint注释定义在类上,通过类路径扫描自动检测。spring-doc.cadn.net.cn