#java #spring #spring-batch
#java #весна #spring-batch
Вопрос:
У меня есть проблема с моим писателем, когда afterStep()
он не вызывается:
public class MyWriter implements ItemStreamWriter<MyDTO>, StepExecutionListener {
private FlatFileItemWriter<MyDTO> delegate;
private Resource resource;
public void setDelegate(final FlatFileItemWriter<MyDTO> delegate) {
this.delegate = delegate;
delegate.setResource(resource);
}
public void setResource(final Resource resource) {
this.resource = resource;
if (delegate != null) {
delegate.setResource(resource);
}
}
@Override
public void write(List<? extends MyDTO> items) throws Exception {
delegate.write(items);
}
@Override
public void open(ExecutionContext executionContext) throws ItemStreamException {
delegate.open(executionContext);
}
@Override
public void update(ExecutionContext executionContext) throws ItemStreamException {
delegate.update(executionContext);
}
@Override
public void close() throws ItemStreamException {
delegate.close();
}
@Override
public void beforeStep(StepExecution stepExecution) {
// do nothing
}
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
// do nothing
return null;
}
У меня также есть пошаговый охват боба:
@Bean
@StepScope
public ItemStreamWriter<MyDTO> itemWriter() {
DelimitedLineAggregator<MyDTO> lineAggregator = new DelimitedLineAggregator<>();
BeanWrapperFieldExtractor<MyDTO> extractor = new BeanWrapperFieldExtractor<>();
extractor.setNames(new String[]{"test"});
lineAggregator.setFieldExtractor(extractor);
MyWriter writer = new MyWriter();
FlatFileItemWriter<MyDTO> flatFileItemWriter = new FlatFileItemWriter<>();
flatFileItemWriter.setLineAggregator(lineAggregator);
flatFileItemWriter.setShouldDeleteIfExists(true);
flatFileItemWriter.afterPropertiesSet();
writer.setDelegate(flatFileItemWriter);
writer.setResource(new FileSystemResource(getRequestOutputResource(blah)));
return writer;
}
Ответ №1:
Возвращаемый тип компонента writer ItemStreamWriter
равен , поэтому компонент прокси — сервера с пошаговой областью действия , создаваемый Spring Batch , не будет рассматриваться как a StepExecutionListener
. Вам необходимо зарегистрировать своего автора в качестве слушателя выполнения шагов.
В качестве дополнительного примечания, ваш класс делает две вещи (он является автором и слушателем одновременно). Полиморфизм — хорошая идея для некоторых вариантов использования, но в вашем случае я бы выделил каждую логику в отдельный класс для большей ясности и избежания путаницы с прокси.
Комментарии:
1. Не совсем уверен в требуемом изменении. Как зарегистрировать writer в качестве прослушивателя выполнения шага? Какой-нибудь пример, пожалуйста?
2. В вашем определении шага вы делаете что-то вроде:
.writer(myWriter()).listener(myWriter())
. Возможно, вам потребуется привести writer кStepExecutionListener
, чтобы это сработало. Но опять же, я бы отделил логику записи от логики прослушивания в разных классах и заставил бы каждую вещь делать что-то одно и делать это хорошо, потому что так много сложностей в программном обеспечении возникает из-за попыток заставить одну вещь делать две вещи. .3. Я попробовал
.listener((StepExecutionLister) myWriter)
, который не сработал с не удается вызвать исключение. Мне нужно поместить ссылку наresource
в моемItemWriter
классе вexecutionContext
для следующего шага, поэтому мне нужна логика afterstep в том же классе.4. Это не проблема, вы вводите ресурс в writer, поэтому вы также можете ввести его в отдельный прослушиватель и иметь четкое разделение проблем.
5. можете ли вы, пожалуйста, помочь с примером предоставления ресурса, как в моем случае?