Akashic Records

Spring Batch+quartz 연동 본문

Spring.io

Spring Batch+quartz 연동

Andrew's Akashic Records 2023. 3. 31. 23:30
728x90

Spring Batch와 Quartz를 연동하려면 먼저 Quartz를 설정하고, Quartz Job을 생성한 다음에 Spring Batch Job을 Quartz Job 내에서 실행하도록 설정해야 합니다. 다음은 Spring Batch와 Quartz를 연동하는 예시 코드입니다.

의존성 추가:
build.gradle 파일에 Quartz와 Spring Batch의 의존성을 추가합니다.

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-batch'
    implementation 'org.springframework:spring-context-support'
    implementation 'org.quartz-scheduler:quartz:2.3.2'
}

 

Quartz 설정:
Quartz 설정을 위한 QuartzConfig.java 파일을 생성하고, SchedulerFactoryBean을 구성합니다.

import org.quartz.JobDetail;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import java.io.IOException;
import java.util.Properties;

@Configuration
public class QuartzConfig {

    @Autowired
    private ApplicationContext applicationContext;

    @Bean
    public JobDetailFactoryBean jobDetail() {
        JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
        jobDetailFactoryBean.setJobClass(QuartzJobLauncher.class);
        jobDetailFactoryBean.setDurability(true);
        return jobDetailFactoryBean;
    }

    @Bean
    public Trigger trigger(JobDetail jobDetail) {
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(10) // 스케줄링 주기 (예: 10초마다)
                .repeatForever();

        return TriggerBuilder.newTrigger()
                .forJob(jobDetail)
                .withSchedule(scheduleBuilder)
                .build();
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(Trigger trigger, JobDetail jobDetail) throws IOException {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setConfigLocation(new ClassPathResource("quartz.properties"));
        schedulerFactoryBean.setJobFactory(springBeanJobFactory());
        schedulerFactoryBean.setJobDetails(jobDetail);
        schedulerFactoryBean.setTriggers(trigger);

        return schedulerFactoryBean;
    }

    @Bean
    public SpringBeanJobFactory springBeanJobFactory() {
        AutoWiringSpringBeanJobFactory jobFactory = new AutoWiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        return jobFactory;
    }

    @Bean
    public PropertiesFactoryBean quartzProperties() throws IOException {
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        propertiesFactoryBean.setLocation(new ClassPathResource("quartz.properties"));
        propertiesFactoryBean.afterPropertiesSet();
        return propertiesFactoryBean;
    }
}

 

AutoWiringSpringBeanJobFactory.java 파일을 생성하여 Quartz Job이 Spring Bean을 주입 받을 수 있도록 설정합니다.

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;

public final class AutoWiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {

	private transient AutowireCapableBeanFactory beanFactory;

    @Override
    public void setApplicationContext(final ApplicationContext context) {
        beanFactory = context.getAutowireCapableBeanFactory();
    }

    @Override
    protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
        final Object job = super.createJobInstance(bundle);
        beanFactory.autowireBean(job);
        return job;
    }
}


Quartz Job 생성:

`QuartzJobLauncher.java` 파일을 생성하여 Spring Batch Job을 실행하는 Quartz Job을 구성합니다.

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.configuration.JobLocator;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;

public class QuartzJobLauncher implements Job {

    @Autowired
    private JobLauncher jobLauncher;

    @Autowired
    private JobLocator jobLocator;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        try {
            JobParameters jobParameters = new JobParametersBuilder()
                    .addLong("time", System.currentTimeMillis())
                    .toJobParameters();

            // "myJob"은 Spring Batch Job의 이름입니다.
            jobLauncher.run(jobLocator.getJob("myJob"), jobParameters);
        } catch (Exception e) {
            throw new JobExecutionException(e);
        }
    }
}

 

Spring Batch Job 구성:
예를 들어, 간단한 Spring Batch Job을 작성하고 이를 실행합니다.

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.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;
import java.util.List;

@Configuration
@EnableBatchProcessing
public class BatchConfig {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job myJob(Step myStep) {
        return jobBuilderFactory.get("myJob")
                .start(myStep)
                .build();
    }

    @Bean
    public Step myStep(ItemReader<String> reader, ItemWriter<String> writer) {
        return stepBuilderFactory.get("myStep")
                .<String, String>chunk(1)
                .reader(reader)
                .writer(writer)
                .build();
    }

    @Bean
    public ItemReader<String> reader() {
        List<String> data = Arrays.asList("Hello", "World");
        return new ListItemReader<>(data);
    }

    @Bean
    public ItemWriter<String> writer() {
        return items -> items.forEach(System.out::println);
    }
}


이제 프로젝트를 실행하면, Quartz 스케줄러가 설정된 주기에 따라 Spring Batch Job이 실행됩니다. 이 예제에서는 10초마다 Job이 실행되도록 설정되어 있습니다.

728x90

'Spring.io' 카테고리의 다른 글

Spring Boot+JWT 구현  (0) 2023.04.03
Spring Boot+WebSocket 구현  (0) 2023.03.31
Spring Boot Actuator  (0) 2023.03.23
Spring All Dependency Injection Types  (0) 2021.02.19
Spring Boot Project 만들기  (0) 2021.01.26
Comments