[JAVA] Étape de boucle avec Spring Batch

En tant qu'image, je veux boucler step``` avec une instruction for. Comment faire cela avec la définition `` job '' de spring-batch.

Code source

pom.xml

pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.6.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<groupId>kagami</groupId>
	<artifactId>springbatchsample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>springbatchsample</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version><!-- https://qiita.com/kagamihoge/items/fbfe90837192fd88fee9 -->
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-batch</artifactId>
		</dependency>
		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.batch</groupId>
			<artifactId>spring-batch-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>

App

package kagami.springbatchsample.deciders;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.Step;
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.launch.support.RunIdIncrementer;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@EnableBatchProcessing
@SpringBootApplication
public class App {

  @Bean
  public Job job(JobBuilderFactory jobs, @Qualifier("s1") Step s1, JobExecutionDecider decider) {
    return jobs
        .get("myJob")
        .incrementer(new RunIdIncrementer())
        .start(s1)
        .next(decider)
          .on("COMPLETED").end()
          .on("CONTINUE").to(s1)
         .end()
        .build();
  }

  @Bean(name = "s1")
  public Step step1(StepBuilderFactory steps) {
    return steps.get("step1").tasklet((stepContribution, chunkContext) -> {
      System.out.println("step 1");
      return RepeatStatus.FINISHED;
    }).build();
  }
  
  @Bean
  public JobExecutionDecider decider() {
    return new JobExecutionDecider() {
      int count = 0;
      @Override
      public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
        if (++count >= 5) {
          return new FlowExecutionStatus("COMPLETED");
        } else {
          return new FlowExecutionStatus("CONTINUE");
        }
      }
    };
  }

  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }

}

En utilisant JobExecutionDecider pour spring-batch, la prochaine exécution `étape` Vous pouvez implémenter la logique pour déterminer. Dans l'exemple de code ci-dessus, nombre '' correspond à cette logique. JobExecutionDecider`` est ici](https://www.omotenashi-mind.com/index.php?title=SpringBatch%EF%BC%9A%E3%83%AB%E3%83%BC% E3% 83% 97% E5% 87% A6% E7% 90% 86% E3% 82% 92% E5% BF% 9C% E7% 94% A8% E3% 81% 97% E3% 81% 9F% E3% 82% B5% E3% 83% 96% E3% 83% 95% E3% 83% AD% E3% 83% BC% E5% AE% 9F% E7% 8F% BE% E6% 96% B9% E6% B3% Je l'ai implémenté en référence à 95).

Ensuite, utilisez l'implémentation de JobExecutionDecider``` dans la définition job. Dans l'exemple de code ci-dessus, si la valeur de retour de `` `` JobExecutionDecider est COMPLETED '' , elle se termine et si elle est CONTINUE '' `, alors` `step Est exécuté. En conséquence, `` `` step est exécuté à plusieurs reprises jusqu'à ce que la condition `` count '' soit satisfaite.

Vous trouverez ci-dessous le journal d'exécution.

2019-06-20 11:50:20.305  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
step 1
2019-06-20 11:50:20.347  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Duplicate step [step1] detected in execution of job=[myJob]. If either step fails, both will be executed again on restart.
2019-06-20 11:50:20.349  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
step 1
2019-06-20 11:50:20.356  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Duplicate step [step1] detected in execution of job=[myJob]. If either step fails, both will be executed again on restart.
2019-06-20 11:50:20.358  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
step 1
2019-06-20 11:50:20.366  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Duplicate step [step1] detected in execution of job=[myJob]. If either step fails, both will be executed again on restart.
2019-06-20 11:50:20.368  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
step 1
2019-06-20 11:50:20.375  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Duplicate step [step1] detected in execution of job=[myJob]. If either step fails, both will be executed again on restart.
2019-06-20 11:50:20.377  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
step 1

Duplicate step [step1] detected ...sur. Comme vous pouvez le voir dans le journal, la même étape est utilisée plusieurs fois dans un même travail, et si l'une ou l'autre des étapes échoue, les deux seront exécutées au redémarrage. Cela semble vouloir dire que ce type de phénomène doit être pris en compte lors du redémarrage.



# Les références
* https://www.omotenashi-mind.com/index.php?title=SpringBatch%EF%BC%9A%E3%83%AB%E3%83%BC%E3%83%97%E5%87%A6%E7%90%86%E3%82%92%E5%BF%9C%E7%94%A8%E3%81%97%E3%81%9F%E3%82%B5%E3%83%96%E3%83%95%E3%83%AD%E3%83%BC%E5%AE%9F%E7%8F%BE%E6%96%B9%E6%B3%95


Recommended Posts

Étape de boucle avec Spring Batch
[Tutoriel] Spring Batch
Résumé de ce que j'ai appris dans Spring Batch
Inject Logger au printemps
Utilisez Interceptor au printemps
J'ai essayé Spring Batch
Microservices dans Spring Cloud
Obtenez des cookies au printemps
Comment utiliser CommandLineRunner dans Spring Batch of Spring Boot
ORA-08177 lorsque Spring Batch est exécuté en continu dans Oracle
Comment utiliser le référentiel de jobs en mémoire avec Spring Batch
[Spring Batch] Vérification de la mise en œuvre de l'étape de bloc et de l'étape de tâche de Spring Batch
Définir le paramètre contextuel dans Spring Boot
Paramètres de lancement de tâche Spring Batch
Multi-projets Spring Boot 2 avec Gradle
Erreur de connexion à la base de données Spring
NoHttpResponseException dans Spring Boot + WireMock
Comment utiliser Lombok au printemps
Chaîne d'appels depuis la chaîne dans l'intégration Spring
Spring Boot Hello World dans Eclipse
Développement d'applications Spring Boot dans Eclipse
Environnement Java Spring dans vs Code
Écrire du code de test avec Spring Boot
Exécuter des applications Java dans Azure Batch
J'ai participé au JJUG CCC 2019 Spring
Implémenter reCAPTCHA v3 dans Java / Spring
Implémenter l'API REST avec Spring Boot
Qu'est-ce que @Autowired dans Spring Boot?
Implémenter l'application Spring Boot dans Gradle
Comment utiliser Thymeleaf avec Spring Boot