Я хочу создать задание с этим потоком:
execute step1
if (resource doesn't exist)
execute createStep
else
execute updateStep
Я создал решающее значение для возврата «СОЗДАТЬ» или «ОБНОВИТЬ». Мой решающий элемент определяется с помощью @Service, поэтому bean-компонент будет автоматически подключен
мой рабочий процесс следующий:
return jobs.get("someJobName")
.start(step1())
.next(myDecider).on("CREATE").to(createStep())
.from(myDecider).on("UPDATE").to(updateStep())
.end().build();
Когда я запускаю свой UnitTest, он выполняет все шаги, создает и обновляет, как будто он запустил решающий второй раз, выбрав оба пути. Что я делаю неправильно?
Мне нравится.
Ниже приведен пример работы одного класса, сохраняющий ту же структуру в потоке работы.
Невозможно за один прогон получить системное сообщение для CREATE
и UPDATE
.
Сравните его с вашей установкой, и если вы по-прежнему сталкиваетесь с проблемами, включите в описание выполняющийся код.
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.StepExecution;
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.scope.context.ChunkContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import java.util.Random;
@EnableBatchProcessing
@SpringBootApplication
public class DemoApplication {
@Autowired
StepBuilderFactory stepBuilderFactory;
@Autowired
JobBuilderFactory jobBuilderFactory;
@Bean
MyDecider myDecider() {
return new MyDecider();
}
@Bean
Step stepInit() {
return stepFactoryWithMessage("stepInit");
}
@Bean
Step createStep() {
return stepFactoryWithMessage("createStep");
}
@Bean
Step updateStep() {
return stepFactoryWithMessage("updateStep");
}
@Bean
Job job() {
return this.jobBuilderFactory.get("job")
.start(stepInit())
.next(myDecider()).on("CREATE").to(createStep())
.from(myDecider()).on("UPDATE").to(updateStep())
.end()
.build();
}
static class MyDecider implements JobExecutionDecider {
public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
String status;
if (new Random().nextBoolean()) {
status = "CREATE";
}
else {
status = "UPDATE";
}
return new FlowExecutionStatus(status);
}
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
private Step stepFactoryWithMessage(String stepName) {
return this.stepBuilderFactory.get(stepName)
.tasklet(
(StepContribution stepContribution, ChunkContext chunkContext) -> {
System.out.println("from " + stepName);
return RepeatStatus.FINISHED;
}).build();
}
}
Ага. Когда я запускаю загрузочное приложение, оно запускает только один из тасклетов. Это появляется только тогда, когда я запускаю модульные тесты. JobExecution jobExecution = jobLauncherTestUtils.launchJob () Есть подсказки по этому поводу?
Поскольку это происходило только в модульных тестах, я изменил способ их запуска, и теперь он работает правильно.
Я поддерживаю этот ответ. Протестировано и работает, как ожидалось, в соответствии с тем, что задано в вопросе.