обработчик afterstep не вызывается в ItemWriter

#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. можете ли вы, пожалуйста, помочь с примером предоставления ресурса, как в моем случае?