簡體   English   中英

Spring Batch 條件流不執行 else 部分

[英]Spring Batch Conditional Flow Not executing the else part

我正在嘗試使用 Spring 批處理實現下圖所示的流程。 我指的是https://docs.spring.io/spring-batch/4.0.x/reference/pdf/spring-batch-reference.pdf 的第 85 頁上的 java 配置,它討論了 Java 配置。

要求

出於某種原因,當判定器返回 TYPE2 時,批處理以失敗狀態結束,沒有任何錯誤消息。 以下是我工作的java配置:

jobBuilderFactory.get("myJob")
            .incrementer(new RunIdIncrementer())
            .preventRestart()
            .start(firstStep())
            .next(typeDecider()).on("TYPE1").to(stepType1()).next(lastStep())
            .from(typeDecider()).on("TYPE2").to(stepType2()).next(lastStep())
            .end()
            .build();

我認為 java 配置有問題,盡管它與 Spring 文檔匹配。 流程在這里很有用,但我相信沒有它會有辦法。 關於如何實現這一目標的任何想法?

您不僅需要定義從stepType1到后續步驟的流程,還需要定義從stepType1stepType2lastStep 下面是一個例子:

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
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.job.flow.FlowExecutionStatus;
import org.springframework.batch.core.job.flow.JobExecutionDecider;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.repeat.RepeatStatus;
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 Step firstStep() {
        return steps.get("firstStep")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("firstStep");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public JobExecutionDecider decider() {
        return (jobExecution, stepExecution) -> new FlowExecutionStatus("TYPE1"); // or TYPE2
    }

    @Bean
    public Step stepType1() {
        return steps.get("stepType1")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("stepType1");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Step stepType2() {
        return steps.get("stepType2")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("stepType2");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Step lastStep() {
        return steps.get("lastStep")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("lastStep");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Job job() {
        return jobs.get("job")
                .start(firstStep())
                .next(decider())
                    .on("TYPE1").to(stepType1())
                    .from(decider()).on("TYPE2").to(stepType2())
                    .from(stepType1()).on("*").to(lastStep())
                    .from(stepType2()).on("*").to(lastStep())
                    .build()
                .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());
    }

}

這打印:

firstStep
stepType1
lastStep

如果決策程序返回TYPE2 ,則示例打印:

firstStep
stepType2
lastStep

希望這可以幫助。

遇到了類似的問題,即沒有調用 else 部分(從技術上講,只調用了首先配置的 on())

幾乎所有與流程和決策程序示例相關的網站都有類似的作業配置,無法弄清楚是什么問題。

經過一些研究,找到了 spring 如何維護決策者和決策的方式。 在高層,在初始化應用程序時,spring 基於作業配置維護決策對象(如 decsion0、decision1 等)的決策列表。

當我們調用決策者()方法時,它總是為決策者返回一個新對象。 當它返回一個新對象時,該列表只包含每個對象的一個​​映射(即 decision0 )並且由於它是一個列表,它總是返回第一個配置的決策。所以這就是為什么只有第一個配置的轉換才被叫。

解決方案:不是對決策程序進行方法調用,而是為決策程序創建一個單例 bean 並在作業配置中使用它

例子:

@Bean
public JobExecutionDecider stepDecider() {
    return new CustomStepDecider();
}

注入它並在作業創建 bean 中使用它

@Bean
public Job sampleJob(Step step1, Step step2,Step step3,
JobExecutionDecider stepDecider) {

return jobBuilderFactory.get("sampleJob")                    
        .start(step1)
        .next(stepDecider).on("TYPE1").to(step2)
        .from(stepDecider).on("TYPE2").to(step3)


}

希望這可以幫助。

創建一個 dummyStep,它將返回 FINISH 狀態並跳轉到下一個決策程序。 完成當前步驟后,您需要將流光標重定向到下一個決策程序或虛擬步驟

.next(copySourceFilesStep())
.next(firstStepDecider).on(STEP_CONTINUE).to(executeStep_1())
.from(firstStepDecider).on(STEP_SKIP).to(virtualStep_1())

//-executeStep_2
.from(executeStep_1()).on(ExitStatus.COMPLETED.getExitCode())
.to(secondStepDecider).on(STEP_CONTINUE).to(executeStep_2())
.from(secondStepDecider).on(STEP_SKIP).to(virtualStep_3())

.from(virtualStep_1()).on(ExitStatus.COMPLETED.getExitCode())
.to(secondStepDecider).on(STEP_CONTINUE).to(executeStep_2())
.from(secondStepDecider).on(STEP_SKIP).to(virtualStep_3())

//-executeStep_3
.from(executeStep_2()).on(ExitStatus.COMPLETED.getExitCode())
.to(thirdStepDecider).on(STEP_CONTINUE).to(executeStep_3())
.from(thirdStepDecider).on(STEP_SKIP).to(virtualStep_4())

.from(virtualStep_3()).on(ExitStatus.COMPLETED.getExitCode())
.to(thirdStepDecider).on(STEP_CONTINUE).to(executeStep_3())
.from(thirdStepDecider).on(STEP_SKIP).to(virtualStep_4())

@Bean
public Step virtulaStep_2() {
    return stepBuilderFactory.get("continue-virtualStep2")
            .tasklet((contribution, chunkContext) -> {
                return RepeatStatus.FINISHED;
            })
            .build();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM