用于从全局线控中排除特定通道的模式

时间:2016-01-19 21:00:28

标签: spring spring-integration

我有一个全球电话线,我用它来进行审计。由于有线窃听没有从通道中获取消息的克隆,我从消息中提取某些属性并将其转发到另一个(异步)通道,在该通道中它被持久化。所以从某种意义上说,线控有它自己的子流。我意识到有线分接不会自我敲击,但我希望它不会挖掘任何属于持久性子流的通道。

我意识到线控有一个模式,但似乎不接受正则表达式来排除不应全局分接的通道。提供排除模式的格式是什么?

2 个答案:

答案 0 :(得分:2)

来自@GlobalChannelInterceptor JavaDocs:

/**
 * An array of simple patterns against which channel names will be matched. Default is "*"
 * (all channels). See {@link org.springframework.util.PatternMatchUtils#simpleMatch(String, String)}.
 * @return The pattern.
 */
String[] patterns() default "*";

所以,根据PatternMatchUtils.simpleMatch,我们可以:

* Match a String against the given pattern, supporting the following simple
* pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy" matches (with an
* arbitrary number of pattern parts), as well as direct equality.

如你所见,我们不能否定模式。

从另一方面来说,我认为我们可以克服这个限制。如您所见WireTap实现VetoCapableInterceptor,其逻辑如下:

public boolean shouldIntercept(String beanName, ChannelInterceptorAware channel) {
    return !this.channel.equals(channel);
}

因此,您可以扩展此WireTap类并为overrode方法添加更多逻辑。之后,您应该在XML配置中将其注册为<bean>的{​​{1}}。

答案 1 :(得分:0)

使用Artem的建议,我能够解决这个问题,但我一路上有一些小问题,所以我只留下我的实现的shell,以防其他人遇到同样的问题:

我做的第一件事是实现一个扩展WireTap类的类。这个班看起来像这样 -

package org.mycompany.interceptors;

import org.springframework.integration.channel.ChannelInterceptorAware;
import org.springframework.integration.channel.interceptor.WireTap;
import org.springframework.integration.support.context.NamedComponent;
import org.springframework.messaging.MessageChannel;

public class GlobalWireTap extends WireTap {

    public GlobalWireTap(MessageChannel channel) {
        super(channel);
    }

    @Override
    public boolean shouldIntercept(String beanName, ChannelInterceptorAware interceptChannel) {
        NamedComponent incomingChannel = (NamedComponent) interceptChannel;
        String channelName = incomingChannel.getComponentName();
        /* logic to determine if this channel should be intercepted */
        if (channelName.startsWith("DNT")) {
            return false;
        }
        return true;
    }
}

如您所见,传入参数的类型为ChannelInterceptorAware。但是,ChannelInterceptorAware并没有告诉我很多关于Channel的内容,因此我将它转换为NamedComponent(每种类型的Channel都实现)并检查通道的id以决定是否要拦截此通道。请注意,在WireTap类中,channel属性是私有的,因此您不能在子类中执行类似 - this.channel的操作。

相应的配置如下所示:

<int:channel-interceptor pattern="*" ref="globalWireTap"></int:channel-interceptor>

<bean id="globalWireTap"
    class="org.mycompany.interceptors.GlobalWireTap">
    <constructor-arg ref="nullChannel" />
</bean> 

现在我将所有消息重定向到nullChannel,但您可以将其转发到任何频道。