Весенний загрузчик пакетного планировщика запускается один раз - PullRequest
1 голос
/ 04 мая 2019

Я начал изучать Spring Boot Batch в версии 2.1.4

Я хочу запустить свою работу в планировщике, и эта работа выполняется только один раз. Я имею в виду ItemProcessor и ItemWriter запускаются только один раз. ItemReader запускается каждый раз. У кого-нибудь есть идея, что я сделал не так. В будущем я хочу изменить планировщик на Java WatchService и передать filePath в задание, но теперь параметр для filePath похож на строку в параметре функции. Это мой код:

Это мой читатель:

@Component
public class UserReaderImpl  {
    @StepScope
    public ItemReader<UserCsvStructure> read(String filepath) {
        FlatFileItemReader<UserCsvStructure> reader = new FlatFileItemReader();
        reader.setLinesToSkip(1);
        reader.setResource(new FileSystemResource(filepath));
        reader.setLineMapper(new DefaultLineMapper<UserCsvStructure>() {
            {
                setLineTokenizer(new DelimitedLineTokenizer() {
                    {
                        setNames(new String[]{"firstName","lastName","email"});
                    }
                });
                setFieldSetMapper(new BeanWrapperFieldSetMapper<UserCsvStructure>() {
                    {
                        setTargetType(UserCsvStructure.class);
                    }
                });
            }
        });
        return reader;
    }
}

Это в моем ItemProcessor

@StepScope
@Component
public class UserProcessorImpl implements ItemProcessor<UserCsvStructure, User> {
@Override
public User process(UserCsvStructure userCsvStructure) throws Exception {
    return User.builder()
            .email(userCsvStructure.getEmail())
            .firstName(userCsvStructure.getFirstName())
            .lastName(userCsvStructure.getLastName())
            .build();
}
}

Это мой ItemWriter

@Component
@StepScope
public class UserWriterImpl implements ItemWriter<User>{
@Autowired
private UserRepository userRepository;

@Override
public void write(List<? extends User> list) throws Exception {
    System.out.println(list);
    userRepository.saveAll(list);
}
}

А это моя конфигурация

@Component
public class UserBatchCsvConfig {

@Autowired
public JobBuilderFactory jobBuilderFactory;

@Autowired
public StepBuilderFactory stepBuilderFactory;

@Autowired
private UserReaderImpl userReader;

@Autowired
private UserWriterImpl userWriter;

@Autowired
private UserProcessorImpl userProcessor;

public Job csvFileToDatabaseJob(UserJobCompletionNotificationListener listener, String fileName) {
    return jobBuilderFactory.get("userCsvProcess")
            .incrementer(new RunIdIncrementer())
            .listener(listener)
            .flow(csvFileToDatabaseStep(fileName))
            .end()
            .build();
}

private Step csvFileToDatabaseStep(String fileName) {
    return stepBuilderFactory.get("userCsvProcess")
            .<UserCsvStructure, User>chunk(1)
            .reader(userReader.read(fileName))
            .processor(userProcessor)
            .writer(userWriter)
            .build();
}

}

Последний класс - мой планировщик:

@Component
public class UserCsvProcessor {

@Autowired
private JobLauncher jobLauncher;

@Autowired
private UserBatchCsvConfig job;

@Autowired
private UserJobCompletionNotificationListener userJobCompletionNotificationListener;

@Scheduled(fixedDelay = 10000)
public void runJob() throws Exception {
    jobLauncher.run(job.csvFileToDatabaseJob(userJobCompletionNotificationListener, "C:\\Users\\Anik\\Desktop\\angular\\test.csv"), new JobParameters());
}
}

Ответы [ 2 ]

0 голосов
/ 07 мая 2019

При наличии конфигурации в аннотации @Scheduled вы указываете, что она будет выполняться каждые 10 секунд. Итак, когда ваше первое выполнение будет завершено, оно будет ждать 10 секунд, а затем выполнит его снова и так далее.

@Scheduled(fixedDelay = 10000)

Если вы хотите выполнить его один раз (я думаю, это один раз в день), вы можете использовать выражение cron в аннотации @Scheduled. Посмотрите на приведенный ниже пример, где выражение cron указывает, что метод должен выполняться каждый день в 10:15 утра.

@Scheduled(cron = "0 15 10 * * *")

Если вы хотите запускать его раз в месяц / год, вы можете обработать выражение cron, чтобы сделать это. Кроме того, вы можете прочитать это выражение из файла конфигурации, используя что-то вроде следующего:

@Scheduled(cron = "${cron.expression}")
0 голосов
/ 04 мая 2019

Я знаю, что мне добавить в мой код В классе UserCsvProcessor мне нужно изменить запланированную функцию на:

@Scheduled(fixedDelay = 10000)
public void runJob() throws Exception {
    JobParameters params = new JobParametersBuilder()
            .addString("JobID", String.valueOf(System.currentTimeMillis()))
            .toJobParameters();
    jobLauncher.run(job.csvFileToDatabaseJob(userJobCompletionNotificationListener, "C:\\Users\\Anik\\Desktop\\angular\\test.csv"), params);
}

Если у кого-то есть другая идея или идея получше, просто добавьте ответ

...