Spring集成-带有DSL的FtpInboundFileSynchronizer比较器配置

问题描述

Spring Integration的FtpInboundFileSynchronizer允许设置Comparator<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不应在上下文之外构造。 (尽管这似乎确实起作用。)但是,在那种情况下,如何使用配置有Comparator<FTPFile>的同步器动态组装ftp集成流?

解决方法

好像我们错过了在DSL中公开remoteComparator选项一样。

随时提出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-extensions

因此,您可以扩展FtpInboundChannelAdapterSpec,以提供缺少的选项来为内部synchronizer配置。