Spring Batch - RepositoryItemReader从ExecutionContext读取参数

时间:2018-02-05 15:35:02

标签: spring spring-data-jpa spring-batch

我有Spring Batch作业,我在两个stpes之间传递一些值。我在Step1中的Job Context中设置了值,现在尝试从Step2中的RepositoryItemReader读取。有@BeforeStep方法,我可以在上下文中读取值集。但是我在@PostConstruct注释方法中设置我的存储库以及方法名称和args,该方法在@BeforeStep注释方法之前执行。

从JobExecution Context中读取ReposiotryItem中的param的最佳方法是什么?

v1 <- c('56.17-', -56.17, 56.17)

2 个答案:

答案 0 :(得分:1)

您的读者需要成为@StepScoped而不是@JobScoped。即使您正在访问作业上下文,在上一步完成之前,该值在上下文中不可用。如果你@StepScope你的读者,它将不会初始化,直到它是启动的一部分并且值可用。

另一种选择是在@Configuration文件中将读者构造为@Bean定义,但想法是一样的。这使用SpEL进行后期绑定。

@Configuration
public class JobConfig {

    // Your item reader will get autowired into this method
    // so you don't have to call it
    @Bean
    public Step myStep(MyItemReader myItemReader) {
        //build your step
    }

    @Bean
    @StepScope
    public MyItemReader myItemReader(@Value("#{jobExecutionContext[partitionKey]}") Integer lastIdPulled) {
        MyItemReader reader = new MyItemReader();
        // Perform @PostConstruct tasks
        return reader;
    }
}

答案 1 :(得分:0)

我能够弄清楚如何解决您的问题并找到我的方法,而不必在@Configuration文件中创建@Bean定义并且无需使用@PostConstruct。

代替使用@PostConstruct,只需在类的构造函数中进行设置,并在@BeforeStep中设置参数,如下所示:

@Component
@StepScope
public class MyItemReader extends RepositoryItemReader<Scan> {


@Autowired
public MyItemReader(MyRepository myRepository) {
    super();
    this.setRepository(MyRepository myRepository);
    this.setMethodName("findByGreaterThanId");

    final Map<String, Sort.Direction> sorts = new HashMap<>();
    sorts.put("id", Direction.ASC);
    this.setSort(sorts);      
}

@BeforeStep
public void initializeValues(StepExecution stepExecution) {
    Integer value = stepExecution.getJobExecution().getExecutionContext().getInt("lastIdPulled");
    System.out.println(">>>>>>>> last_pulled_id = " + value);

    List<Object> methodArgs = new ArrayList<Object>();
    if(lastIdPulled== null || lastIdPulled<=0 ){
       lastScanIdPulled = 0;
    }
    methodArgs.add(lastIdPulled);
    this.setArguments(methodArgs);
}
}