以下是我正在使用的配置
@Autowired
private SftpRemoteFileTemplate outboundTemplate;
@Autowired
private SftpConfig config;
@Bean
@ServiceActivator(inputChannel = "sftpOutputGenericChannel")
public MessageHandler simplehandler() {
SftpMessageHandler handler = new SftpMessageHandler(outboundTemplate, FileExistsMode.APPEND);
handler.setRemoteDirectoryExpression(new LiteralExpression(config.getDirectory()));
handler.setFileNameGenerator((Message<?> message) -> ((String) message.getHeaders().get(KEY)));
handler.setUseTemporaryFileName(false);
return handler;
}
我在单独的Config类中创建了Sessionfactory,CachingSessionfactory和SftpRemoteFileTemplte,并且它们已正确实例化,以下是相同的日志。
2020-11-27 01:15:17.742 [main] o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'cachingSessionFactory'
2020-11-27 01:15:17.744 [main] o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'sftpSessionFactory'
2020-11-27 01:15:17.778 [main] o.s.b.f.s.DefaultListableBeanFactory : Autowiring by type from bean name 'cachingSessionFactory' via factory method to bean named 'sftpSessionFactory'
2020-11-27 01:15:17.783 [main] o.s.integration.util.SimplePool : Target pool size changed by -2147483637, now 10
2020-11-27 01:15:54.434 [main] o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'outboundTemplate'
2020-11-27 01:15:54.435 [main] o.s.b.f.s.DefaultListableBeanFactory : Autowiring by type from bean name 'outboundTemplate' via factory method to bean named 'cachingSessionFactory'
当我执行此代码时,Spring DEBUG日志显示文件已成功发送到服务器,但实际上文件并未上载到服务器。
但是如果我将的实现更改MessageHandler
为
SftpMessageHandler handler = new SftpMessageHandler(new SftpRemoteFileTemplate(cachingSessionFactory), FileExistsMode.APPEND);
它开始工作,文件实际上已上传到服务器,不确定为什么会发生这种情况吗?
当我@Autowired SftpRemoteFileTemplate
与handler.setRemoteDirectoryExpressionString("headers['remote_directory']")
它一起使用时,可以再观察一次。
我想了解SftpRemoteTemplate在这里如何工作,建议的最佳做法是什么?
注意:SpringBoot v2.4.0 Spring集成:5.4.1,面对引导v2.2.6.RELEASE的类似问题
你可能SftpRemoteFileTemplate
在其他地方使用了相同的名称,并且还在其他地方对其进行了修改。实际上handler.setRemoteDirectoryExpression()
,对提供的对象进行了委派,因此发生了变化SftpRemoteFileTemplate
:
/**
* Specify a remote directory path SpEL expression.
* @param remoteDirectoryExpression the remote directory expression
* @see RemoteFileTemplate#setRemoteDirectoryExpression(Expression)
*/
public void setRemoteDirectoryExpression(Expression remoteDirectoryExpression) {
this.remoteFileTemplate.setRemoteDirectoryExpression(remoteDirectoryExpression);
}
因此,当另一个地方进行类似的修改时,你最终会遇到争用情况,并且你的文件可能会转移到另一个地方。
最佳做法是将aRemoteFileTemplate
视为a,prototype
并且每个通道适配器都有一个实例。或仅使用另一个ctor-仅SessionFactory
基于-:
/**
* @param sessionFactory the session factory.
* @see FileTransferringMessageHandler#FileTransferringMessageHandler
* (SessionFactory)
*/
public SftpMessageHandler(SessionFactory<LsEntry> sessionFactory)
我们可能需要修改的逻辑,FileTransferringMessageHandler
以拒绝外部提供的突变RemoteFileTemplate
。随时提出GH问题,我们将在下一个主要版本中看到可以做什么,在该版本中我们可以进行一些重大更改。
感谢Artem,我现在将只使用新的SftpRemoteFileTemplate。我试过使用PROTOTYPE范围和多个其他选项,以及在初始化SftpRemoteFileTemplate时设置远程目录和不调用处理程序的方法等,但是结果是相同的。.我可以使用另一个仅使用SessionFactory的ctor,但不确定是否会给我一个选择在追加模式下写入文件?这样我就不需要到处使用SftpRemoteFileTemplate