Java Spring Job Scheduler 구현하기 (반복/단일 실행 설정 가능)

스프링 애플리케이션 내에서 특정 작업(Job)을 백그라운드에서 반복하거나 단 한 번만 실행하고 싶을 때가 있을 것이다!
이번 포스트에서는 간단한 Job 인터페이스와 JobScheduler 클래스를 이용해 유연하게 실행되는 잡 시스템을 구현하는 방법을 정리했다.

📌 구조 요약

  • CustomJob: 각 Job이 따라야 할 인터페이스
  • JobScheduler: 스프링 빈 초기화 시점에 Job을 별도 스레드로 실행
  • GoogleToDataJob: 실제 실행할 Job 구현체 예시

1. CustomJob 인터페이스

public interface CustomJob {
    String getJobName();          // Job 이름
    long getSleepMillis();        // 반복 시 대기 시간(ms)
    void execute();               // Job 실행 로직

    default boolean isRepeatable() {
        return true; // 기본은 반복 실행
    }
}

 
 
getJobName(): 각 Job마다 고유 이름을 설정한다.
getSleepMillis(): 반복 주기를 밀리초 단위로 반환한다.
execute(): 실제 작업이 실행되는 메서드
isRepeatable(): 기본은 true로 반복 실행되며, false로 오버라이드하면 한 번만 실행된다.
 

2. JobScheduler 클래스

@Component
public class JobScheduler implements InitializingBean {

    private final List<CustomJob> jobs;

    @Value("${job.name:}")
    private String jobName;

    public JobScheduler(List<CustomJob> jobs) {
        this.jobs = jobs;
    }

    @Override
    public void afterPropertiesSet() {
        for (CustomJob job : jobs) {
            if (job.getJobName().equals(jobName)) {
                Thread thread = new Thread(() -> {
                    try {
                        if (job.isRepeatable()) {
                            while (!Thread.currentThread().isInterrupted()) {
                                job.execute();
                                Thread.sleep(job.getSleepMillis());
                            }
                        } else {
                            job.execute(); // 단일 실행
                        }
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    } catch (Exception ex) {
                        System.err.println("[ERROR] " + job.getJobName() + ": " + ex.getMessage());
                    }
                }, job.getJobName() + "-Scheduler");

                thread.setDaemon(true);
                thread.start();
                System.out.println("[JobScheduler] " + job.getJobName() + " 스케줄러 시작됨");
            }
        }
    }
}

@Value("${job.name}")  : 프로퍼티값에 따라 해당되는 job이 스레드로 실행이 된다.

3. GoogleToDataJob – 반복 실행 Job 예제

@Component("GoogleToDataJob")
public class GoogleToDataJob implements CustomJob {

    private final Logger log = LoggerFactory.getLogger(GoogleToDataJob.class);

    @Autowired
    private SchduleLogService schduleLogService;

    @Value("${spring.manaview.job.sleeptime}")
    private long SLEEP_TIME;

    @Override
    public String getJobName() {
        return "GoogleToDataJob";
    }

    @Override
    public long getSleepMillis() {
        return SLEEP_TIME;
    }

    @Override
    public void execute() {
        MDC.put("scheduleName", "googlega4");
        try {
            log.info("##[GOOGLE GA MANAVIEW] START!");
        } catch (Exception e) {
            e.printStackTrace();
        }
        MDC.clear();
    }
}
 

GoogleToDataJob이름의 job이 실행된다.
반복주기는 프로퍼티에 설정된 값을 따르며 job마다 이름이 다른 log 파일을 위해 MDC에 내가 원하는 파일명으로 put을 한다.
 

반복하지 않는 Job으로 설정하고 싶다면?

@Override
public long getSleepMillis() {
    return 0; // 반복 안 하니까 의미 없음
}

@Override
public boolean isRepeatable() {
    return false; // 단일 실행
}

isRepeatable 값을 false 로 지정하면 JobScheduler에서 해당 설정을 감지해 반복없이 한번만 호출하게 된다.
 

사용한 Gradle 의존성 (필수 모듈만 정리)

이 Job Scheduler를 구성하기 위해 필요한 주요 라이브러리는 다음과 같다.

dependencies {
    // Spring 기본 모듈
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-web'

    // 스케줄링 및 배치 처리
    implementation 'org.springframework.boot:spring-boot-starter-batch' // Spring Batch 기반 반복 작업 구성 가능

    // Lombok (코드 간결화용)
    compileOnly 'org.projectlombok:lombok:1.18.30'
    annotationProcessor 'org.projectlombok:lombok:1.18.30'
}

 

주의할점 : Application.properties 설정 

# Spring Batch 자동 실행 방지 (중요!)
spring.batch.job.enabled=false

# 웹 애플리케이션이 아닌 배치 전용 실행 (웹 환경 제거)
spring.main.web-application-type=none

# 반복 주기 (예: 10초 간격)
spring.manaview.job.sleeptime=10000

Spring Batch를 사용하는 경우, 기본적으로 애플리케이션 실행 시 모든 Job이 자동 실행되기 때문에,
직접 스케줄러로 Job을 관리할 때는 자동 실행을 끄는 설정이 반드시 필요하다.
또한, 웹 UI가 필요 없는 콘솔 기반 실행이라면 spring.main.web-application-type=none 도 설정하도록 하자.
 
배포를 한후에는,
java -jar batch-job-1.0.0.jar --job.name=GoogleToDataJob
실행하면 해당 job 프로그램이 실행하는것을 확인할수 있다.