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

use*_*166 9 java spring spring-batch

我正在尝试制作一个Spring 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>
Run Code Online (Sandbox Code Playgroud)

并且getSQLs触发一个bean,该bean执行一个类,该类生成一个String类型的List.是否可以引用runSQLs触发的bean列表?("触发"可能不是正确的术语,但我想你知道我的意思)

更新:所以getSQLs步骤触发这个bean:

<bean id="runGetSQLs" class="myTask"
    scope="step">
    <property name="filePath" value="C:\Users\username\Desktop\sample.txt" />
</bean>
Run Code Online (Sandbox Code Playgroud)

它触发执行此方法的myTask类:

  @Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {

    ExecutionContext stepContext = this.stepExecution.getExecutionContext();
    stepContext.put("theListKey", sourceQueries);

    return RepeatStatus.FINISHED;
}
Run Code Online (Sandbox Code Playgroud)

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

tma*_*wen 10

Spring Batch支持将数据推送到未来的工作步骤,这可以通过ExecutionContext更准确的方式完成JobExecutionContext.这里我指的是官方文档中的示例,因为它是我的最终参考:

要使数据可用于将来的步骤,必须在步骤完成后将其"提升"到Job ExecutionContext.Spring Batch为此提供了ExecutionContextPromotionListener.

应该使用您的步骤配置监听器,该步骤与未来的数据共享数据:

<batch:step id="getSQLs" next="runSQLs">
    <batch:tasklet transaction-manager="TransactionManager"
        ref="runGetSQLs" />
    <listeners>
        <listener>
            <beans:bean id="promotionListener" class="org.springframework.batch.core.listener.ExecutionContextPromotionListener">
                <beans:property name="keys" value="theListKey"/>
            </beans:bean>
        </listener>
    </listeners>
</batch:step>

<batch:step id="runSQLs">
    <batch:tasklet transaction-manager="TransactionManager"
        ref="runRunSQLs" />
</batch:step>
Run Code Online (Sandbox Code Playgroud)

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

// ...
ExecutionContext stepContext = this.stepExecution.getExecutionContext();
stepContext.put("theListKey", yourList);
Run Code Online (Sandbox Code Playgroud)

然后在后续步骤中,List可以使用带有@BeforeStep如下注释的后计算挂钩检索:

@BeforeStep
public void retrieveSharedData(StepExecution stepExecution) {
    JobExecution jobExecution = stepExecution.getJobExecution();
    ExecutionContext jobContext = jobExecution.getExecutionContext();
    this.myList = jobContext.get("theListKey");
}
Run Code Online (Sandbox Code Playgroud)

  • 奇怪的是,将数据从一个步骤传递到下一个步骤的最常见用例并未得到满足,并且您对作业上下文解决方案进行了这种奇怪的推广.如果您有一个分区程序然后并行运行步骤,则此解决方案不起作用. (4认同)

Nir*_*ane 6

java配置方式。

第 1 步:配置 ExecutionContextPromotionListener

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

    }
Run Code Online (Sandbox Code Playgroud)


第 2 步:使用 ExecutionContextPromotionListener @Bean配置步骤

    public Step myStep() {
        return stepBuilderFactory.get("myStep")
                .<POJO, POJO> chunk(1000)
                .reader(reader()                
                .processor(Processor())
                .writer(Writer()
                .listener(promotionListener())
                .build();
    }
Run Code Online (Sandbox Code Playgroud)

步骤 3:访问​​处理器中的数据

    @BeforeStep
    public void beforeStep(StepExecution stepExecution) {
         jobExecutionContext = stepExecution.getJobExecution().getExecutionContext();
         jobExecutionContext.getString("MY_KEY")
    }
Run Code Online (Sandbox Code Playgroud)

步骤4:在处理器中设置数据

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