반응형

공통

build.gradle.kts

dependencies {
    // ...
    implementation("org.springframework.boot:spring-boot-starter-batch")    
    runtimeOnly("org.hsqldb:hsqldb")    
}

JobDatabaseConfig

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

    @Bean
    public PlatformTransactionManager jobTransactionManager(@Qualifier("jobDataSource") DataSource jobDataSource) {
        return new JdbcTransactionManager(jobDataSource);
    }
}

BatchConfig

@RequiredArgsConstructor
@Configuration
public class BatchConfig extends DefaultBatchConfiguration {
    @Qualifier("jobDataSource")
    private final DataSource jobDataSource;

    @Qualifier("jobTransactionManager")
    private final PlatformTransactionManager jobTransactionManager;

    @Override
    protected DataSource getDataSource() {
        return jobDataSource;
    }

    @Override
    protected PlatformTransactionManager getTransactionManager() {
        return jobTransactionManager;
    }
}

DemoTasklet

@Slf4j
@StepScope // jobParameters 사용시 필요
@Component
public class DemoTasklet implements Tasklet {
    @Value("#{jobParameters['field1']}")
    private String field1;

    @Value("#{jobParameters['field2']}")
    private String field2;

    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
        log.info("run demoTasklet. field1: {}, field2: {}", field1, field2);
        return RepeatStatus.FINISHED;
    }
}

DemoJobConfig

@RequiredArgsConstructor
@Configuration
public class DemoJobConfig {
    private final JobRepository jobRepository;

    @Qualifier("jobTransactionManager")
    private final PlatformTransactionManager jobTransactionManager;

    @Bean
    public Job demoJob(Step demoStep) {
        return new JobBuilder("demoJob", jobRepository)
            .start(demoStep)
            .build();
    }

    @Bean
    public Step demoStep(Tasklet demoTasklet) {
        return new StepBuilder("demoStep", jobRepository)
            .tasklet(demoTasklet, jobTransactionManager)
            .build();
    }
}

Command Line으로 배치 실행하기

BatchRunner

@RequiredArgsConstructor
@Component
public class BatchRunner implements CommandLineRunner {
    private final JobLauncher jobLauncher;
    private final List<Job> jobList;

    @Override
    public void run(String... args) throws Exception {
        Map<String, String> params = Arrays.stream(args).map(it -> it.split("=")).collect(Collectors.toMap(it -> it[0].trim(), it -> it[1].trim()));

        String jobName = params.get("jobName");
        params.remove("jobName");

        JobParametersBuilder builder = new JobParametersBuilder();
        params.forEach(builder::addString);

        Job job = jobList.stream().filter(it -> it.getName().equals(jobName)).findFirst().orElseThrow(() -> new IllegalStateException(jobName + " is not supported job"));
        jobLauncher.run(job, builder.toJobParameters());
    }
}

실행

java -jar batch-demo.jar jobName=demoJob field1=value1 field2=value2

API로 배치 실행하기

BatchController

@RequiredArgsConstructor
@RestController
public class BatchController {
    private final JobLauncher jobLauncher;
    private final List<Job> jobList;

    @PostMapping("/api/batch/launch/{jobName}")
    public void launchJob(@PathVariable String jobName, @RequestParam Map<String, String> parameters) throws Exception {
        JobParametersBuilder builder = new JobParametersBuilder();
        parameters.forEach(builder::addString);

        Job job = jobList.stream().filter(it -> it.getName().equals(jobName)).findFirst().orElseThrow(() -> new BadRequestException(jobName + " is not supported job"));
        jobLauncher.run(job, builder.toJobParameters());
    }
}

실행

curl -X POST "http//localhost:8080/api/batch/launch/demoJob?field1=value1&field2=value2"
반응형

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

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

+ Recent posts