반응형

들어가며

예제 설명

  • 아래는 phoneNumber에 '-'가 포함된 전화번호를 '-'가 없는 전화번호로 바꾸는 배치 예제 코드이다.
  • 사용한 의존성 라이브러리의 버전은 아래와 같다.
    • spring-boot-starter-batch:3.2.3
    • spring-batch-core:5.1.1

예제 코드

dependencies

implementation("org.springframework.boot:spring-boot-starter-batch")
implementation("org.hsqldb:hsqldb") // dataSource로 in-memory db 사용을 위해 필요

BatchConfig

@Configuration
public class BatchConfig {
    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.HSQL)
            .addScript("/org/springframework/batch/core/schema-hsqldb.sql")
            .generateUniqueName(true)
            .build();
    }
}

BeforeUser

@Getter
@RequiredArgsConstructor
public class BeforeUser {
    private final String phoneNumber;
}

AfterUser

@Getter
@RequiredArgsConstructor
public class AfterUser {
    private final String phoneNumber;
}

UserItemReader

@Component
public class UserItemReader implements ItemReader<BeforeUser> {
    private static final List<BeforeUser> RAW_USERS = List.of(
        new BeforeUser("000-0000-0000"),
        new BeforeUser("111-1111-1111"),
        new BeforeUser("222-2222-2222")
    );

    private int index = 0;

    @Override
    public BeforeUser read() {
        return (index < RAW_USERS.size()) ? RAW_USERS.get(index++) : null;
    }
}

UserItemProcessor

@Component
public class UserItemProcessor implements ItemProcessor<BeforeUser, AfterUser> {
    @Override
    public AfterUser process(BeforeUser item) {
        String afterPhoneNumber = item.getPhoneNumber().replace("-", "");
        return new AfterUser(afterPhoneNumber);
    }
}

UserItemWriter

@Component
public class UserItemWriter implements ItemWriter<AfterUser> {
    @Override
    public void write(Chunk<? extends AfterUser> chunk) {
        chunk.getItems().forEach(it -> {
            System.out.println(it.getPhoneNumber());
        });
    }
}

UserJobConfig

@Configuration
public class UserJobConfig extends DefaultBatchConfiguration {
    @Bean
    public Job userJob(
        JobRepository jobRepository,
        Step userStep
    ) {
        return new JobBuilder("userJob", jobRepository)
            .start(userStep)
            .build();
    }

    @Bean
    public Step userStep(
        JobRepository jobRepository,
        PlatformTransactionManager transactionManager,
        UserItemReader userItemReader,
        UserItemProcessor userItemProcessor,
        UserItemWriter userItemWriter
    ) {
        return new StepBuilder("userStep", jobRepository)
            .<BeforeUser, AfterUser>chunk(2, transactionManager)
            .reader(userItemReader)
            .processor(userItemProcessor)
            .writer(userItemWriter)
            .build();
    }
}

Application

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

Command Line으로 Job 실행하기

BatchConfig

@Configuration
public class BatchConfig {
    ...

    // 아래 코드 추가
    @Bean
    public JobLauncherApplicationRunner jobLauncherApplicationRunner(
        @Value("${job.name}") String jobName,
        JobLauncher jobLauncher,
        JobExplorer jobExplorer,
        JobRepository jobRepository
    ) {
        JobLauncherApplicationRunner runner = new JobLauncherApplicationRunner(jobLauncher, jobExplorer, jobRepository);
        runner.setJobName(jobName);
        return runner;
    }
}

실행

java -jar -Djob.name=userJob demo.jar

출력

00000000000
11111111111
22222222222

API로 Job 실행하기

dependencies

implementation("org.springframework.boot:spring-boot-starter-web") // 추가

JobLaunchController

@RequiredArgsConstructor
@RestController
public class JobLaunchController {
    private final JobLauncher jobLauncher;
    private final Map<String, Job> jobs;

    @GetMapping("/api/job/launch/{jobName}")
    public void launchJob(@PathVariable String jobName) throws Exception {
        Job job = Optional.ofNullable(jobs.get(jobName)).orElseThrow(() -> new BadRequestException(jobName + " is not exist"));
        jobLauncher.run(job, new JobParameters());
    }
}

실행

curl http://localhost:8080/api/job/launch/userJob

출력

00000000000
11111111111
22222222222
반응형

'Development > Spring Batch' 카테고리의 다른 글

[Spring Batch] 기본 개념  (0) 2024.03.09

+ Recent posts