简体   繁体   English

访问作业参数 Spring Batch

[英]Accessing Job Parameters Spring Batch

I have been struggling with accessing Job Parameters of a job using spring batch.我一直在努力使用 spring 批处理访问作业的作业参数。 Here is my implementation so far.到目前为止,这是我的实现。

@Configuration
@EnableBatchProcessing
@PropertySource("classpath:batch.properties")
public class CSVBatchServiceImpl extends StepExecutionListenerSupport implements CSVBatchService {
    private static final Logger LOGGER = LoggerFactory.getLogger(CSVBatchServiceImpl.class);
    @Autowired
    public JobBuilderFactory jobBuilderFactory;
    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    private QuestionReader questionReader = new QuestionReader();

    @Bean(name = "importQuestionsJob")
    public Job importQuestionsJob() {
        return jobBuilderFactory.get("importQuestionsJob")
                .incrementer(new RunIdIncrementer())
                .flow(step1())
                .end()
                .build();
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .<Question, Question>chunk(2)
                .reader(questionReader.reader())
                .processor(processor())
                .build();
    }

    @Bean
    public QuestionProcessor processor() {
        return new QuestionProcessor();
    }
}

class QuestionReader extends StepExecutionListenerSupport {
    private static final Logger LOGGER = LoggerFactory.getLogger(QuestionReader.class);

    //TODO: remove this
    private static JsonNode getJsonNode(String str) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            return mapper.readTree(str);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Bean
    public FlatFileItemReader<Question> reader() {
        FlatFileItemReader<Question> reader = new FlatFileItemReader<>();
        //TODO get this as a parameter
        reader.setResource(new ClassPathResource("duplicateLabels.csv"));
        reader.setLinesToSkip(1);
        reader.setLineMapper(new DefaultLineMapper<Question>() {{
            setLineTokenizer((new DelimitedLineTokenizer() {{
                setNames(new String[]{"label", "body", "real_answer"});
            }}));
            setFieldSetMapper(new QuestionFieldSetMapper());
        }});
        return reader;
    }

    private static class QuestionFieldSetMapper implements FieldSetMapper<Question> {
        public Question mapFieldSet(FieldSet fieldSet) {
            Question question = new Question();
            question.setLabel(fieldSet.readString(0));
            question.setBody(getJsonNode(fieldSet.readString(1)));
            question.setRealAnswer(getJsonNode(fieldSet.readString(2)));
            return question;
        }
    }
}

I am calling the job like:我称这项工作为:

JobParameters parameters = new JobParametersBuilder()
        .addLong("time", System.currentTimeMillis())
        .addString("filePath", "file.csv")
        .toJobParameters();
jobLauncher.run(importQuestionsJob, parameters);

How can I go about accessing the filePath parameter inside reader function?如何访问读取器函数中的 filePath 参数?

Another solution that works very well for ItemProcessors , ItemReaders , ItemWriters and so on is the @BeforeStep annotation.另一个非常适用于ItemProcessorsItemReadersItemWriters等的解决方案是@BeforeStep注释。 It is backed by a StepExecutionListener just like Eugene To mentioned .它由StepExecutionListener支持,就像Eugene To 提到的那样 It is kind of a shortcut for that solution.这是该解决方案的一种捷径。

An implementation might look like this一个实现可能看起来像这样

@BeforeStep
public void beforeStep(StepExecution stepExecution) {
    JobParameters jobParameters = stepExecution.getJobParameters();

    Long millis = jobParameters.getLong("time");
    String path = jobParameters.getString("filePath");
}

You should be able to do ,你应该能够做到,

@Value("#{jobParameters['filePath']}") String filePath;

In case of any issues, you may try putting your reader in @StepScope .如有任何问题,您可以尝试将您的读者放在@StepScope

You may add org.springframework.batch.core.listener.JobParameterExecutionContextCopyListener to your Step.您可以将org.springframework.batch.core.listener.JobParameterExecutionContextCopyListener添加到您的步骤。

TaskletStep step = stepBuilderFactory.get("my-best-step") .<Item, Item>chunk(10) .reader(myBestReader) .writer(myBestWriter) .listener(new JobParameterExecutionContextCopyListener()) .build();

That Listener will copy JobParameters to ExecutionContext that is available in ItemReader's open and update methods该侦听器将JobParameters复制到 ItemReader 的 open 和 update 方法中可用的ExecutionContext

One of the ways to access the Job Parameters is to implement StepExecutionListener to your reader Class to make use of its Overridden methods beforeStep and afterStep,访问作业参数的方法之一是为您的阅读器类实现 StepExecutionListener 以利用其覆盖的方法 beforeStep 和 afterStep,

@Override
public void beforeStep(StepExecution stepExecution) {
   String filePath = (String) stepExecution.getJobExecution().getExecutionContext()
        .get("filePath");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM