Java 在Spring中在步骤之间传递信息?

Java 在Spring中在步骤之间传递信息?,java,spring,spring-batch,Java,Spring,Spring Batch,我正在试着做一个春季批次,但我没有这方面的经验 是否可以传递每个批处理步骤的信息,或者它们必须完全独立 例如,如果我有 <batch:step id="getSQLs" next="runSQLs"> <batch:tasklet transaction-manager="TransactionManager" ref="runGetSQLs" /> </batch:step> <batch

我正在试着做一个春季批次,但我没有这方面的经验

是否可以传递每个批处理步骤的信息,或者它们必须完全独立

例如,如果我有

   <batch:step id="getSQLs" next="runSQLs">
        <batch:tasklet transaction-manager="TransactionManager"
            ref="runGetSQLs" />
    </batch:step>

    <batch:step id="runSQLs">
        <batch:tasklet transaction-manager="TransactionManager"
            ref="runRunSQLs" />
    </batch:step>

我是否需要以某种方式将stepExecution传递给execute方法?

Spring Batch支持将数据推送到未来的作业步骤,这可以通过
ExecutionContext
完成,更准确地说是
JobExecutionContext
。这里我指的是,因为它是我的终极参考:

为了使数据可用于未来的步骤,必须 步骤完成后,“升级”到作业执行上下文。 Spring批处理为此提供ExecutionContextPromotionListener 目的

侦听器应配置您的步骤,即与将来的步骤共享数据的步骤:


应从执行代码块中填充数据,如下所示:

/。。。
ExecutionContext stepContext=this.stepExecution.getExecutionContext();
放置(“列表键”,您的列表);
然后,在后续步骤中,可以使用带有
@BeforeStep
a注释的post-computation钩子检索该
列表,如下所示:

@BeforeStep
公共无效检索共享数据(步骤执行步骤执行){
JobExecution JobExecution=stepExecution.getJobExecution();
ExecutionContext jobContext=jobExecution.getExecutionContext();
this.myList=jobContext.get(“列表键”);
}
java配置方式

步骤1:配置ExecutionContextPromotionListener

@Bean
    public ExecutionContextPromotionListener executionContextPromotionListener()
    {
        ExecutionContextPromotionListener executionContextPromotionListener = new ExecutionContextPromotionListener();
        executionContextPromotionListener.setKeys(new String[] {"MY_KEY"});
        return executionContextPromotionListener;   

    }
    @BeforeStep
    public void beforeStep(StepExecution stepExecution) {
         jobExecutionContext = stepExecution.getJobExecution().getExecutionContext();
         jobExecutionContext.getString("MY_KEY")
    }
步骤2:使用ExecutionContextPromotionListener配置步骤 @豆子

    public Step myStep() {
        return stepBuilderFactory.get("myStep")
                .<POJO, POJO> chunk(1000)
                .reader(reader()                
                .processor(Processor())
                .writer(Writer()
                .listener(promotionListener())
                .build();
    }
步骤4:在处理器中设置数据

@BeforeStep
        public void beforeStep(StepExecution stepExecution) {
            stepExecution.getJobExecution().getExecutionContext().put("MY_KEY", My_value);
        }

如果您想使用ExecutionContext在步骤之间传递信息,我建议您三思。通常这意味着工作设计得不完美。springbatch的主要思想是处理大量的数据。ExecutionContext用于存储有关作业/步骤进度的信息,以在出现故障时减少不必要的工作。在设计上,您无法将大数据放入ExecutionContext。在完成一个步骤后,您应该以可靠可读的形式获得信息—文件、数据库等。这些数据可以在后续步骤中用作输入。对于简单的作业,我建议只使用作业参数作为信息源


在您的例子中,“runGetSQLs”看起来不是一个很好的步骤候选,但是如果您愿意,您可以在“runsqls”步骤中将其实现为Springbean和autowire(这同样是一个很好的步骤候选)。根据您的命名,runGetSQLs看起来像ItemReader,runsqls看起来像itemrater。因此,它们是一个步骤的一部分,而不是不同的步骤。在这种情况下,您不需要将信息传输到其他步骤。

我的代码似乎无法识别步骤执行。我导入了org.springframework.batch.core.StepExecution。我在这里遗漏了什么?你应该用你的代码块更新帖子,并提及你到目前为止所做的事情。我还更改了步骤以匹配您的示例。奇怪的是,从一个步骤到下一个步骤传递数据的最常见用例没有得到满足,而且您有一个奇怪的晋升到工作上下文解决方案。如果您有一个分区器,该分区器然后并行运行步骤,则此解决方案不起作用。@该分区器也会污染DB
BATCH\u JOB\u EXECUTION\u CONTEXT。带有中间数据的序列化\u CONTEXT
不是最佳解决方案。在作业步骤之间传递数据的要求意味着您违反了批处理规则。谢谢,Niraj。这就是我所期待的。
    @BeforeStep
    public void beforeStep(StepExecution stepExecution) {
         jobExecutionContext = stepExecution.getJobExecution().getExecutionContext();
         jobExecutionContext.getString("MY_KEY")
    }
@BeforeStep
        public void beforeStep(StepExecution stepExecution) {
            stepExecution.getJobExecution().getExecutionContext().put("MY_KEY", My_value);
        }