问题描述
Spring Integration的FtpInboundFileSynchronizer
允许设置Comparator<FTPFile>
以允许对下载进行排序。该文档说:
这对于@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
作为动态流的一种解决方法,我确实建议单独使用FtpInboundFileSynchronizer
和FtpInboundFileSynchronizingMessageSource
,然后使用提到的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
配置。