file:inbound-channel-adapter 在使用自定义扫描仪时失败

file:inbound-channel-adapter fails when using a custom scanner

我正在使用 spring 集成 4.2。4.RELEASE 我遇到了一个错误。我正在尝试使用基于 "WatchServiceDirectoryScanner" 的自定义目录创建入站通道。当我尝试注入此扫描仪时出现错误。

"The 'filter' and 'locker' options must be present on the provided external 'scanner': "。无论我尝试过哪种属性组合,它都不起作用。原因是因为即使我为我的自定义扫描仪提供储物柜和过滤器,spring 中的 "FileReadingMessageSource" 也会创建它们自己的。因此,当它断言

Assert.state(!(this.scannerExplicitlySet && (this.filter != null || this.locker != null)),
                "The 'filter' and 'locker' options must be present on the provided external 'scanner': "
                        + this.scanner);

它失败了。有一个过滤器是 "FileListFilterFactoryBean.initializeFileListFilter",无论设置了什么组合,下面的代码都会创建一个过滤器,但整个过程都会失败。

        // no filters are provided
        else if (Boolean.FALSE.equals(this.preventDuplicates)) {
            filtersNeeded.add(new AcceptAllFileListFilter<File>());
        }
        else { // preventDuplicates is either TRUE or NULL
            filtersNeeded.add(new AcceptOnceFileListFilter<File>());
        }

我已阅读post:How to skip the settings of filter and locker 但它对我不起作用。 有人找到解决方案了吗?

这是创建入站渠道的示例 XML 配置。

        <bean id="inboundChannel_3522_filter" class="org.springframework.integration.file.filters.CompositeFileListFilter">
        <constructor-arg>
            <list>
                <bean class="org.springframework.integration.file.filters.RegexPatternFileListFilter">
                    <constructor-arg value="^Test_(20160216).TXT$" />
                </bean>
            </list>
        </constructor-arg>
    </bean>
    <bean id="inboundChannel_3522_nio_locker" class="org.springframework.integration.file.locking.NioFileLocker" />
    <bean id="inboundChannel_3522_scanner" class="com.test.spring.integraton.file.NonRecursiveWatchServiceDirectoryScanner"
>
        <constructor-arg value="e:\data\incoming\Test-V2" />
        <property name="filter" ref="inboundChannel_3522_filter"/> 
        <property name="locker" ref="inboundChannel_3522_nio_locker"/> 
    </bean>
    <file:inbound-channel-adapter  id="inboundChannel_3522"  auto-create-directory="true"  scanner="inboundChannel_3522_scanner" 
 directory="file:/c:/data/incoming/TEST/"  prevent-duplicates="false"  ignore-hidden="false"  >
        <integration:poller fixed-rate="1000"/>
    </file:inbound-channel-adapter>

基本上我想知道是否有任何方法可以覆盖 bean FileReadingMessageSource 以便我可以更改 Assert?

我已经弄清楚如何解决这个错误。所以我创建了一个扫描仪,并将过滤器和储物柜注入扫描仪。我创建了一个自定义 FileReadingMessageSourceFactoryBean,如果已注入扫描器,它会跳过创建过滤器和储物柜。具有更改的 CustomFileReadingMessageSourceFactoryBean 如下所示。更改发生在第 172 行。其余相同。

            if (this.scanner != null)
        {
            this.source.setScanner(this.scanner);
        }
        else
        {
            if (this.filter != null)
            {
                if (this.locker == null)
                {
                    this.source.setFilter(this.filter);
                }
                else
                {
                    CompositeFileListFilter<File> compositeFileListFilter = new CompositeFileListFilter<File>();
                    compositeFileListFilter.addFilter(this.filter);
                    compositeFileListFilter.addFilter(this.locker);
                    this.source.setFilter(compositeFileListFilter);
                    this.source.setLocker(locker);
                }
            }
            else if (this.locker != null)
            {
                CompositeFileListFilter<File> compositeFileListFilter = new CompositeFileListFilter<File>();
                compositeFileListFilter.addFilter(new FileListFilterFactoryBean().getObject());
                compositeFileListFilter.addFilter(this.locker);
                this.source.setFilter(compositeFileListFilter);
                this.source.setLocker(locker);
            }
        }

新的 Spring XML 如下所示。不同的是我们在最后添加了bean inboundChanel_3522.adapter.source。这样做的目的是当入站通道查找类型为 FileReadingMessageSourceFactoryBean 的 bean 时,它会将“.adpater.source”附加到其 id,如果存在,它将使用它,否则它将创建一个默认值。在这种情况下,它将使用我们的 CustomFileReadingMessageSourceFactoryBean,它具有跳过创建其他过滤器的逻辑。自定义 bean 在 inbound-channel-adapter 之后出现非常重要,否则 bean 工厂将覆盖它。最后是 XML 的样子。

 <bean id="inboundChannel_3522_filter" class="org.springframework.integration.file.filters.CompositeFileListFilter">
     <constructor-arg>
         <list>
             <bean class="org.springframework.integration.file.filters.RegexPatternFileListFilter">
                 <constructor-arg value="^Test_(20160216).TXT$" />
             </bean>
         </list>
     </constructor-arg>
</bean>
<bean id="inboundChannel_3522_nio_locker" class="org.springframework.integration.file.locking.NioFileLocker" />
<bean id="inboundChannel_3522_scanner" class="com.test.spring.integraton.file.NonRecursiveWatchServiceDirectoryScanner">
    <constructor-arg value="e:\data\incoming\Test-V2" />
    <property name="filter" ref="inboundChannel_3522_filter"/> 
    <property name="locker" ref="inboundChannel_3522_nio_locker"/> 
</bean>
<file:inbound-channel-adapter  id="inboundChannel_3522"  auto-create-directory="true"  
    scanner="inboundChannel_3522_scanner" 
    directory="file:/c:/data/incoming/TEST/"  prevent-duplicates="false"  ignore-hidden="false"  >
    <integration:poller fixed-rate="1000"/>
</file:inbound-channel-adapter>
<bean id="inboundChannel_3522.adapter.source" class="com.test.spring.integraton.file.CustomFileReadingMessageSourceFactoryBean">
    <property name="scanner" ref="inboundChannel_3522_scanner"/> 
    <property name="directory" value="e:\data\incoming\Test-V2"/> 
    <property name="autoCreateDirectory" value="true"/> 
</bean>