#java #spring #spring-boot #spring-integration #spring-integration-sftp
#java #весна #весенняя загрузка #spring-интеграция #spring-интеграция-sftp
Вопрос:
Ниже приведена конфигурация, которую я использую
@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;
}
Я создал 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 показывают, что файл успешно отправлен на сервер, но на самом деле файл не загружается на сервер.
но если я изменю реализацию MessageHandler
на,
SftpMessageHandler handler = new SftpMessageHandler(new SftpRemoteFileTemplate(cachingSessionFactory), FileExistsMode.APPEND);
он начинает работать, и файл фактически загружается на сервер, не уверен, почему это происходит?
Еще одно наблюдение, когда я использую @Autowired SftpRemoteFileTemplate
с handler.setRemoteDirectoryExpressionString("headers['remote_directory']")
ним, работает отлично.
Я хочу понять, как здесь работает SftpRemoteTemplate и какова наилучшая предлагаемая практика?
Примечание: SpringBoot v2.4.0 Spring integration: 5.4.1 столкнулся с аналогичной проблемой при загрузке v2.2.6.RELEASE
Ответ №1:
Вероятно, вы используете то же 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);
}
Таким образом, когда в другом месте выполняется аналогичная модификация, вы получаете состояние гонки, и ваш файл может быть перенесен в другое место.
Лучше всего рассматривать a RemoteFileTemplate
как a prototype
и иметь экземпляр для каждого адаптера канала. Или просто используйте другой ctor — only на SessionFactory
основе:
/**
* @param sessionFactory the session factory.
* @see FileTransferringMessageHandler#FileTransferringMessageHandler
* (SessionFactory)
*/
public SftpMessageHandler(SessionFactory<LsEntry> sessionFactory)
Вероятно, нам нужно пересмотреть логику в FileTransferringMessageHandler
, чтобы отклонить мутацию для предоставленной извне RemoteFileTemplate
. Не стесняйтесь поднимать проблему GH, и мы посмотрим, что мы можем сделать в следующей основной версии, где мы можем внести некоторые критические изменения.
Комментарии:
1. Спасибо, Артем, теперь я буду придерживаться только нового SftpRemoteFileTemplate. Я пытался использовать область ПРОТОТИПА и множество других параметров, а также устанавливать удаленный каталог при инициализации SftpRemoteFileTemplate, а не вызывать метод обработчика и т. Д., Но Результаты те же.. Я могу использовать другой ctor, который использует только SessionFactory, но не уверен, что это даст мне возможность записать файл в режиме добавления? Так что мне не нужно использовать SftpRemoteFileTemplate везде