Java 访问Spring批处理中的作业参数

Java 访问Spring批处理中的作业参数,java,spring,spring-boot,java-8,spring-batch,Java,Spring,Spring Boot,Java 8,Spring Batch,我一直在努力使用SpringBatch访问作业的作业参数。这是我到目前为止的实现 @Configuration @EnableBatchProcessing @PropertySource("classpath:batch.properties") public class CSVBatchServiceImpl extends StepExecutionListenerSupport implements CSVBatchService { private static final L

我一直在努力使用SpringBatch访问作业的作业参数。这是我到目前为止的实现

@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;
        }
    }
}

如何在读卡器函数中访问filePath参数?

您应该能够

@Value("#{jobParameters['filePath']}") String filePath;
如果出现任何问题,您可以尝试将阅读器放入@StepScope。

您可以将org.springframework.batch.core.listener.JobParameterExecutionContextCopyListener添加到步骤中

TaskletStep=stepBuilderFactory.getmy-best-step .10 .readermyBestReader .writermyBestWriter .listener新作业参数ExecutionContextCopyListener .建造


该侦听器将把JobParameters复制到ExecutionContext,ExecutionContext在ItemReader的open和update方法中可用

另一个非常适合的解决方案是注释。它的背后是一个类似于。这是解决这个问题的一种捷径

实现可能如下所示

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

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

访问作业参数的方法之一是对reader类实现StepExecutionListener,以利用其重写的beforeStep和afterStep方法

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

设置作用域是必须的,如果不使用它,将无法工作。如果您能告诉我在哪里可以添加代码,我将非常感激。我想,您需要在reader方法中使用它,以便您可以更改reader签名,如,reader@Value{jobParameters['filePath']}字符串文件路径,但请确保使用@StepScope注释读取器。在步骤定义中,可以为该参数传递null,如questionReader.readernull。
@Override
public void beforeStep(StepExecution stepExecution) {
   String filePath = (String) stepExecution.getJobExecution().getExecutionContext()
        .get("filePath");
}