Spring Batch-将参数从Writer传递给AfterJob(JobExecution jobExecution)的侦听器

时间:2018-11-09 18:55:27

标签: java spring spring-batch

我有一个作家,我从中有一个动态值,需要将其传递给JobExecutionListener的afterJob(JobExecution jobExecution)。希望能得到一些建议。谢谢。

<beans:bean>
    <job id="GoodJob">
        <step id="XXX"
              allow-start-if-complete="true"
              parent="XXX">
            <tasklet transaction-manager="XXX">
                <chunk reader="READER"
                       writer="WRITER"
                       commit-interval="100"/>
            </tasklet>
        </step>

        <listener>
            <beans:bean class="class that implements JobExecutionListener">
                <beans:constructor-arg name="value"
                                       value="DEFAULT IS FALSE DURING INITIALIZATION/MIGHT GET CHANGED IN WRITER, GET THIS VALUE FROM WRITER"/>
            </beans:bean>
        </listener>
    </job>
</beans:beans>

1 个答案:

答案 0 :(得分:1)

您可以通过作业执行上下文在这两个组件之间传递数据。 Passing Data to Future Steps部分对此进行了详细说明。这是一个简单的示例:

import java.util.Arrays;
import java.util.List;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.annotation.BeforeStep;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableBatchProcessing
public class MyJob {

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

    @Bean
    public ItemReader<Integer> itemReader() {
        return new ListItemReader<>(Arrays.asList(1, 2, 3, 4));
    }

    @Bean
    public ItemWriter<Integer> itemWriter() {
        return new ItemWriter<Integer>() {

            private StepExecution stepExecution;

            @Override
            public void write(List<? extends Integer> items) throws Exception {
                for (Integer item : items) {
                    System.out.println("item = " + item);
                }
                stepExecution.getJobExecution().getExecutionContext().put("data", "foo");
            }

            @BeforeStep
            public void saveStepExecution(StepExecution stepExecution) {
                this.stepExecution = stepExecution;
            }

        };
    }

    @Bean
    public Step step() {
        return steps.get("step")
                .<Integer, Integer>chunk(2)
                .reader(itemReader())
                .writer(itemWriter())
                .build();
    }

    @Bean
    public Job job() {
        return jobs.get("job")
                .start(step())
                .listener(new JobExecutionListener() {
                    @Override
                    public void beforeJob(JobExecution jobExecution) {

                    }

                    @Override
                    public void afterJob(JobExecution jobExecution) {
                        ExecutionContext executionContext = jobExecution.getExecutionContext();
                        String data = executionContext.getString("data");
                        System.out.println("data from writer = " + data);
                    }
                })
                .build();
    }

    public static void main(String[] args) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyJob.class);
        JobLauncher jobLauncher = context.getBean(JobLauncher.class);
        Job job = context.getBean(Job.class);
        jobLauncher.run(job, new JobParameters());
    }

}

在此示例中,编写者在作业执行上下文中将键data写入值foo。然后,从作业侦听器的执行上下文中检索此密钥。

希望这会有所帮助。