Как сбросить MultiResourceItemReader для каждого запуска задания. Шаговая область не работает

Как я могу инициализировать MultiResourceItemReader для каждого запуска задания. в настоящее время с этой настройкой он по-прежнему использует один и тот же экземпляр для каждого запуска задания.

Я поместил @StepScope по-прежнему с использованием того же старого списка файлов, которые уже были обработаны. Я не уверен, что еще я должен добавить в этот код

Я также пробовал с @JobScope, но ничего не вышло. есть что-то фундаментальное, что мне не хватает

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

    @Autowired
    public JobBuilderFactory jobBuilderFactory;
    @Autowired
    public StepBuilderFactory stepBuilderFactory;


    @Value("file:ftp-inbound/*.csv")
    @Autowired
    private Resource[] inputResources;

    @Autowired
    private StepBuilderFactory steps;
    @Autowired
    private JobBuilderFactory jobs;
    @Autowired
    private ResourceLoader resourceLoader;


    @Bean
    public FlatFileItemReader<AccommodationRoomAvailability> itemReader() throws UnexpectedInputException, ParseException, IOException {
        FlatFileItemReader<AccommodationRoomAvailability> reader = new FlatFileItemReader<AccommodationRoomAvailability>();
        DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
        String[] tokens = {"Product ID", "Allotment", "Kamertype", "Zoeknaam", "Hotel", "Datum", "Beschikbaar", "Nachten"};
        tokenizer.setNames(tokens);
        tokenizer.setDelimiter(";");
        tokenizer.setStrict(true);
        reader.setLinesToSkip(1);
        DefaultLineMapper<AccommodationRoomAvailability> lineMapper = new DefaultLineMapper<AccommodationRoomAvailability>();
        lineMapper.setLineTokenizer(tokenizer);
        lineMapper.setFieldSetMapper(new RecordFieldSetMapper());
        reader.setLineMapper(lineMapper);

        return reader;
    }

    @Bean
    @Qualifier("multiResourceReader")
    @StepScope
    public MultiResourceItemReader<AccommodationRoomAvailability> multiResourceItemReader() throws Exception {
        MultiResourceItemReader<AccommodationRoomAvailability> resourceItemReader = new MultiResourceItemReader<AccommodationRoomAvailability>();
        resourceItemReader.setResources(inputResources);
        resourceItemReader.setDelegate(itemReader());
        resourceItemReader.setStrict(false);
        resourceItemReader.setSaveState(false);

        // resourceItemReader.read();
        return resourceItemReader;
    }

    @Bean
    public ItemProcessor<AccommodationRoomAvailability, String> itemProcessor() {
        return new AvailabilityProcessor();
    }

    @Bean
    public ItemWriter itemWriter() {
        return new ItemWriter() {
            @Override
            public void write(List list) throws Exception {


            }
        };
    }

    @Bean
    protected Step step1(@Qualifier("multiResourceReader") MultiResourceItemReader<AccommodationRoomAvailability> reader, ItemProcessor<AccommodationRoomAvailability, String> processor,
                         ItemWriter writer) {
        return steps.get("step1")/*.listener(new StepListener())*/.<AccommodationRoomAvailability, String>chunk(30000).reader(reader)
                .processor(processor)
                .writer(writer)
                .build();
    }

    @Bean
    public Step step2() throws IOException {

        FileDeletingTasklet task = new FileDeletingTasklet();
        task.setResources(inputResources);
        return stepBuilderFactory.get("step2")
                .tasklet(task)
                .build();
    }

    @Bean(name = "job")
    public Job job(@Qualifier("step1") Step step1, Step step2) throws IOException {
        return jobs.get("job")
                .start(step1).on("*").to(step2).end()
                // .flow(step1).on("").to(step2()).end()
                .build();
    }

}
0
0
493
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как только контекст вашего приложения будет создан, внедренные ресурсы @Value("file:ftp-inbound/*.csv") будут одинаковыми в течение всего времени существования вашего приложения. Вот почему читатель всегда будет читать одни и те же значения.

Вам нужно передать эти ресурсы в качестве параметра вашей работе и позднее связать их в вашем ридере с областью действия Step. В вашем примере это будет что-то вроде:

@Bean
@Qualifier("multiResourceReader")
@StepScope
public MultiResourceItemReader<AccommodationRoomAvailability> multiResourceItemReader(@Value("#{jobParameters['inputResources']}") Resource[] inputResources) throws Exception {
    MultiResourceItemReader<AccommodationRoomAvailability> resourceItemReader = new MultiResourceItemReader<AccommodationRoomAvailability>();
    resourceItemReader.setResources(inputResources);
    resourceItemReader.setDelegate(itemReader());
    resourceItemReader.setStrict(false);
    resourceItemReader.setSaveState(false);

    return resourceItemReader;
}

Затем передайте входные ресурсы в качестве параметра вашей работе:

JobParameters jobParameters = new JobParametersBuilder()
            .addString("inputResources", "file:ftp-inbound/*.csv")
            .toJobParameters();

currently with this setup its still using the same instance for each job run

Это потому, что ваши ресурсы всегда одинаковы, когда они вводятся в поле вашего класса конфигурации. Если вы используете подход с параметрами задания, о котором я упоминал в предыдущем примере, у вас будет другой экземпляр, если вы запустите задание с другим набором файлов.

Ты прав. Я понял. спасибо за ответ и понятное объяснение.

abhinav jain 09.04.2019 17:20

Другие вопросы по теме