Java + Spring Batch Tasklet + Spring Boot로 Hello World

Jiyul Lee·2021년 4월 21일
0

개요


  • Spring Batch의 Tasklet와 Spring boot의 조합으로 간단한 Hello World 출력 배치 프로그램을 작성

환경


  • Spring Batch 4.3.1 + Spring Boot 2.4.2
  • Java 11 (AdoptOpenJDK 11.0.10+9)
  • Gradle 6.8.1
  • macOS Catalina

Spring Batch의 실행 구성


  • Job가 복수의 step을 호출
  • Step이 Tasklet을 호출

Job

Spring Batch 배치의 도메인 언어 - 레퍼런스

Step은 배치 잡의 독립된 시퀜셜을 캡슐화하는 도메인 오브젝트입니다.
모든 잡은 1개 이상의 스탭으로 완전 구성이 됩니다. Step에서는 실제 배치처리를 정의 및 제어하기우이해 필요한 모든 정보가 포함되어있습니다.

Tasklet

Spring Batch 스탭의 구성 - 레퍼런스 도큐멘트

Tasklet은 execute라는 하나의 메서드를 가지는 단순한 인터페이스입니다.
excute은 RepeatStatus.FINISHED를 반환하거나, 열외을 날려 실패을 알려줄 때 까지 Taskletdp 의해서 반복적으로 호출됩니다.

소스코드


소스트리

|--build.gradle
|--src
    |--main
        |--java
             |--com
                 |--example
                     |--hello
                        |--HelloApplication.java
                        |--HelloConfig.java
                        |--MessageTaklet.java

build.gradle

plugins {
    id 'org.springframework.boot' version '2.4.2'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'com.example'
version = '0.0.1'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}

dependencies {
   //Spring Batch
   implementation 'org.springframework.boot:spring-boot-starter-batch'
   
   // Spring Batch의 메타데이터을 넣는 데이터 소스
   implementation 'com.h2database:h2:1.4.200'
   
   // Lombok
   compileOnly 'org.projectlombok:lombok:1.18.18'
   annotationProcessor 'org.projectlombok:lombok:1.18.18'
}

src/main/java/com/example/hello/HelloApplication.java

package com.example.hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// Spring Boot 어노테이션 클래스
@SpringBootApplication
public class HelloApplication {
    
    public static void main(String[] args) {
    SpringApplication.run(HelloApplication.class, args);
  }
}

src/main/java/com/example/hello/HelloConfig.java

package com.example.hello;

import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.Job;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 배치 구성 클래스
@Configuration // Bean 정의 클래스라는 것을 명시하는 어노테이션
@EnableBatchProcessing // Spring Batch 을 유효화
@RequiredArgsConstructor // Lombok에 의한 생성자 자동 생성

public class HelloConfig {

  private final JobBuilderFactory jobBuilderFactory;
  private final StepBuilderFactory stepBuilderFactory;
  
  @Bean
  public Job fooJob() {
    System.out.println("fooJob 메서드 실행");
    return jobBuilderFactory.get("myFooJob") // 일억성이 되는 임의 잡 이름을 지정
      .flow(helloStep()) // 실행하는 Step을 지정
      .end()
      .build();
  }

  @Bean
  public Job barJob() {
    System.out.println("barJob 메서드 실행");
    return jobBuilderFactory.get("myBarJob") // 일억성이 되는 임의 잡 이름을 지정
      .flow(helloStep()) // 실행하는 Step을 지정
      .next(worldStep()) // 실행하는 Step을 지정
      .end()
      .build();
  }

  @Bean
  public Step helloStep() {
    System.out.println("helloStep 메서드 실행");
    return stepBuilderFactory.get("myHelloStep") // 임의의 스탭 이름을 지정
      .tasklet(new MessageTasklet("Hello!")) // 실행하는 Tasklet을 지정
      .build();
  }

  @Bean
  public Step worldStep() {
    System.out.println("worldStep 메서드를 실행");
    return stepBuilderFactory.get("myWorldStep") // 임의의 스탭 이름을 지정
      .tasklet(new MessageTasklet("World!")) // 실행하는 Tasklet을 지정
      .build();
  }
}

src/main/java/com/example/hello/MessageTasklet.java

package com.example.hello;

import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;

// Tasklet 실행 클래스
@RequiredArgsConstructor // Lombok에 의한 생성자 자동생성
public class MessageTasklet implements Tasklet {

  // 출력 메세지
  private final String message;

  // 구체적인 처리을 코딩하는 메서드
  @Override
  public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
    System.out.println("Message: " + message); // 메세지 출력
    return RepeatStatus.FINISHED; // 처리가 완료된 것을 나타내는 수치 반환
  }
}

빌드


$ gradle build

실행


myFooJob을 실행

$ java -jar build/libs/hello-batch-0.0.1.jar --spring.batch.job.names=myFooJob --logging.level.root=ERROR

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.4.2)

fooJob 메서드을 실행
helloStep 메서드을 실행
barJob 메서드을 실행
worldStep 메서드을 실행
Message: Hello!

myBarJob을 실행

$ java -jar build/libs/hello-batch-0.0.1.jar --spring.batch.job.names=myBarJob --logging.level.root=ERROR

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.4.2)

fooJob 메서드을 실행
helloStep 메서드을 실행
barJob 메서드을 실행
worldStep 메서드을 실행
Message: Hello!
Message: World!

모든 잡을 실행

Spring Boot + Spring Batch의 구성에서는 spring.batch.job.names와 spring.batch.job.enabled=false가 지정된다면 모든 잡이 실행된다.

$ java -jar build/libs/hello-batch-0.0.1.jar --logging.level.root=ERROR

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.4.2)

fooJob 메서드을 실행
helloStep 메서드을 실행
barJob 메서드을 실행
worldStep 메서드을 실행
Message: Hello!
Message: Hello!
Message: World!

참고자료

profile
일본에서 성장 중인 자바 엔지니어

0개의 댓글