首页 > 解决方案 > Spring Integration - 带有 DSL 的 FtpInboundFileSynchronizer 比较器配置

问题描述

Spring IntegrationFtpInboundFileSynchronizer允许设置 aComparator<FTPFile>以允许对下载进行排序。文档说:

从 5.1 版开始,可以为同步器提供比较器。这在限制使用 maxFetchSize 获取的文件数量时很有用。

这对于 @Bean 配置很好:

 @Bean
 public FtpInboundFileSynchronizer ftpInboundFileSynchronizer(...)
        FtpInboundFileSynchronizer synchronizer = new FtpInboundFileSynchronizer(sessionFactory);
        ...
        synchronizer.setComparator(comparator);
        return synchronizer;
    }

但是,如果我想以编程方式组装流程,则鼓励使用 Java DSL。

 StandardIntegrationFlow flow = IntegrationFlows
                .from(Ftp.inboundAdapter(ftpFileSessionFactory, comparator)
                                .maxFetchSize(1)
    ...

工厂方法中的比较器Ftp.inboundAdapter(...)仅用于文件下载后在本地进行比较。这里有一些配置设置会传递给同步器(如远程目录、时间戳等)。但是没有与上面设置等效的同步器设置。

解决方案尝试:

另一种方法是将同步器创建为非 bean,FtpInboundFileSynchronizingMessageSource以类似的方式创建,并IntegrationFlows.from(source)在向流上下文注册流时用于组装同步器导致运行时异常:

Creating EvaluationContext with no beanFactory
java.lang.RuntimeException: No beanFactory
    at org.springframework.integration.expression.ExpressionUtils.createStandardEvaluationContext(ExpressionUtils.java:90) ~[spring-integration-core-5.3.2.RELEASE.jar:5.3.2.RELEASE]
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.afterPropertiesSet(AbstractInboundFileSynchronizer.java:299) ~[spring-integration-file-5.3.2.RELEASE.jar:5.3.2.RELEASE]

那讲得通; FtpInboundFileSynchronizer不应该在上下文之外构建。(虽然这似乎确实有效。)但是,在这种情况下,我如何才能动态组装 ftp 集成流与配置有的同步器Comparator<FTPFile>

标签: springspring-integration

解决方案


看起来我们错过了remoteComparator在 DSL 中公开该选项。

随意提出 GH 问题,甚至提供修复:https ://github.com/spring-projects/spring-integration/issues

作为动态流的解决方法,我真的建议单独使用FtpInboundFileSynchronizerFtpInboundFileSynchronizingMessageSource然后使用提到的IntegrationFlows.from(source). 您在配置中可能错过的是这个 API:

    /**
     * Add an object which will be registered as an {@link IntegrationFlow} dependant bean in the
     * application context. Usually it is some support component, which needs an application context.
     * For example dynamically created connection factories or header mappers for AMQP, JMS, TCP etc.
     * @param bean an additional arbitrary bean to register into the application context.
     * @return the current builder instance
     */
    IntegrationFlowRegistrationBuilder addBean(Object bean);

我的意思FtpInboundFileSynchronizingMessageSource是可以按原样传递给from(),但synchronizer必须作为额外的 bean 添加以进行注册。

另一种更奇特的方法是考虑使用称为 DSL 扩展的新功能:https ://docs.spring.io/spring-integration/docs/5.3.2.RELEASE/reference/html/dsl.html#java-dsl-扩展

因此,您可以扩展它FtpInboundChannelAdapterSpec以提供一个错过的选项来配置内部synchronizer.


推荐阅读