Разбиение пакетов Spring во время выполнения - PullRequest
0 голосов
/ 21 июня 2020

Я хочу прочитать большой файл с помощью Spring Batch. Я хочу разбить на несколько файлов и обрабатывать каждый из них в другом потоке, используя разделы. Я использую приведенный ниже код:

@Bean
@StepScope
public MultiResourcePartitioner partitioner() {
    MultiResourcePartitioner partitioner = new MultiResourcePartitioner();
    partitioner.setKeyName("file");
    partitioner.setResources(splitFiles());
    return partitioner;
}

private Resource[] splitFiles() {
    // Read the large File available in the specified folder
    // split the file to smaller files and return them as resource list
}

@Bean
public TaskExecutorPartitionHandler partitionHandler() {
    TaskExecutorPartitionHandler partitionHandler = new TaskExecutorPartitionHandler();
    partitionHandler.setStep(step1());
    partitionHandler.setTaskExecutor(new SimpleAsyncTaskExecutor());
    return partitionHandler;
}

@Bean
public Step partitionedMaster() {
    return this.stepBuilderFactory.get("step1")
                .partitioner(step1().getName(), partitioner(null))
                .partitionHandler(partitionHandler())
                .build();
}

@Bean
public Job partitionedJob() {
    return this.jobBuilderFactory.get("partitionedJob")
                                .start(partitionedMaster())
                                .build();
}

@Bean
@StepScope
public FlatFileItemReader<Transaction> fileTransactionReader(@Value("#{stepExecutionContext['file']}") Resource resource) {
    return new FlatFileItemReaderBuilder<Transaction>()
                .name("flatFileTransactionReader")
                .resource(resource)
                .fieldSetMapper(fsm)
                .build();
}

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

Как мне читать и разделять файлы динамически во время выполнения?

Редактирование после первого ответа:

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

public JobParameters getJobParameters() {
    Resource[] resources = //getFileToProcessResource
    return new JobParametersBuilder()
            .addLong(TIME, System.currentTimeMillis())
            .addString("inputFiles", resources)
            .toJobParameters();
}

JobParameters jobParameters = getJobParameters();
jobLauncher.run(partitionedJob(), jobParameters);

@Bean
@StepScope
public MultiResourcePartitioner partitioner(@Value("#{jobParameters['inputFiles']}") Resource[] resources) {
    MultiResourcePartitioner partitioner = new MultiResourcePartitioner();
    partitioner.setKeyName("file");
    partitioner.setResources(resources);
    return partitioner;
}

1 Ответ

1 голос
/ 22 июня 2020

После того, как приложение запущено и работает, если новый файл доступен в той же папке, задание не может прочитать их / разделить их

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

Поскольку входными данными вашего задания является файл, вы можете использовать файл в качестве параметра задания и настроить сервис часов (или аналогичный механизм) для запуска нового экземпляра задания для каждого нового файла в папке.

РЕДАКТИРОВАТЬ: Добавьте пример, чтобы разделитель знал о параметре задания

@Bean
@StepScope
public MultiResourcePartitioner partitioner(@Value("#{jobParameters['fileName']}") String fileName) {
    MultiResourcePartitioner partitioner = new MultiResourcePartitioner();
    partitioner.setKeyName("file");
    partitioner.setResources(splitFiles(fileName));
    return partitioner;
}

private Resource[] splitFiles(String fileName) {
    // Read the large File available in the specified folder
    // split the file to smaller files and return them as resource list
    return null;
}
...