#spring-boot #spring-integration #distributed-lock
Вопрос:
Я использую a FileReadingMessageSource
с пользовательским FileLocker
:
@Component
public class JdbcFileLocker implements FileLocker {
...
@Autowired
JdbcFileLocker jdbcFileLocker;
@Bean
@InboundChannelAdapter(value = "fileInputChannel", poller = @Poller(fixedDelay = "1000"))
public MessageSource<File> fileReadingMessageSource() {
FileReadingMessageSource source = new FileReadingMessageSource();
source.setDirectory(new File("/workspace/in"));
source.setFilter(new SimplePatternFileListFilter("input"));
source.getScanner().setLocker(jdbcFileLocker);
return source;
}
Теперь я хочу использовать FileLocker jdbcFileLocker
, чтобы разблокировать файл после обработки его в FileWritingMessageHandler
:
@Bean
@ServiceActivator(inputChannel = "fileInputChannel")
public MessageHandler fileWritingMessageHandler() {
FileWritingMessageHandler fileWritingMessageHandler =
new FileWritingMessageHandler(new File("/workspace/out"));
Должен ли я разблокировать файл самостоятельно @ServiceActivator
или я могу FileLocker
каким-то образом передать свой файл в файлообменник?
ИЗМЕНИТЬ: Добавление ExpressionEvaluatingRequestHandlerAdvice
@Bean
ExpressionEvaluatingRequestHandlerAdvice unlockAdvice() {
ExpressionEvaluatingRequestHandlerAdvice advice =
new ExpressionEvaluatingRequestHandlerAdvice();
advice.setSuccessChannel(unlockChannel);
return advice;
}
Так что я могу добавить это Advice
в свой FileWritingMessageHandler
:
@Autowired
ExpressionEvaluatingRequestHandlerAdvice unlockAdvice;
@Bean
@ServiceActivator(inputChannel = "fileInputChannel")
public MessageHandler fileWritingMessageHandler() {
FileWritingMessageHandler handler =
new FileWritingMessageHandler(new File("/workspace/out"));
handler.setFileExistsMode(FileExistsMode.REPLACE);
handler.setDeleteSourceFiles(true);
handler.setExpectReply(false);
handler.setFileNameGenerator(message -> "output");
handler.setAdviceChain(List.of(unlockAdvice));
return handler;
}
Разблокировка затем обрабатывается @ServiceActivator
прослушиванием unlockChannel
.
Ответ №1:
Прежде всего рассмотрите возможность использования fileWritingMessageHandler.setExpectReply(false)
. Поскольку по умолчанию a FileWritingMessageHandler
ведет себя как шлюз и попытается выдать ответ, который не обрабатывается в вашем потоке, и поэтому вашему опрашивающему будет выдана некоторая ошибка.
Для вашего FileLocker
варианта использования см. активатор ExpressionEvaluatingRequestHandlerAdvice
вашего fileWritingMessageHandler
сервиса. Его onSuccessExpression
можно было бы разблокировать, что действительно будет сделано после FileWritingMessageHandler
завершения процесса. Дополнительную информацию смотрите в документах: https://docs.spring.io/spring-integration/docs/current/reference/html/messaging-endpoints.html#message-handler-advice-chain
Другой способ-иметь a fileInputChannel
как a PublishSubscribeChannel
без изменения конфигурации для текущего fileWritingMessageHandler
. Но вы добавляете в этот канал другого подписчика активатора услуг, который будет выполнять FileLocker.unlock()
логику. Чтобы убедиться, что второй подписчик будет вызван после первого, подумайте о том, чтобы добавить @Order(100)
активатор службы разблокировки для вашего устройства. Также смотрите документы: https://docs.spring.io/spring-integration/docs/current/reference/html/core.html#channel-implementations-publishsubscribechannel
Комментарии:
1. Большое спасибо! Я выбрал
Advice
решение (видно в ПРАВКЕ выше 🙂