繁体   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