본문으로 바로가기

1. @EnableScheduling 어노테이션(Spring Boot 실행 파일)

  • 스프링 스케줄러를 사용하기 위해서는 Spring Boot 실행파일에 @EnableScheduling를 선언해야 사용할 수 있습니다.
  • 선언하지 않을 경우 스케줄러 소스를 작성하더라도 실행이 되지 않습니다.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling
@SpringBootApplication
public class ApiApplication {

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

2. @Scheduled 어노테이션(스케줄러)

  • 스프링 스케줄러를 이용하기 위해서는 스프링 빈으로 등록해야 합니다. 용도에 맞게 어노테이션을 활용하세요
  • @Component, @Controller, @Service, @Repository 
  • @Controller, @Service, @Repository는 @Component를 상속받습니다.
  • 스케줄러 설정을 적용할 메소드에 @Scheduled 어노테이션을 사용합니다.
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Component
public class testScheduler {

    // 3초 간격으로 반복
    @Scheduled(cron = "0/3 * * * * ?")
    public void testPrintRepeat() {
        DateTimeFormatter dtf =  DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
        System.out.println("스케쥴러 테스트 " + LocalDateTime.now().format(dtf));
    }
}

실행 결과

3. Scheduled 인터페이스

  • Scheduled 인터페이스를 보면 사용법을 확인할 수 있습니다. 크론 표현식 외에도 반복 작업을 위해 다양한 방법을 제공합니다.

[사용방법]

String cron() default "";

: cron 표현식을 사용하여 특정 시간마다 동작합니다.

: ("초(second) 분(minute) 시(hour) 일(day of month) 월(month) 요일(day of week)")

 

long fixedDelay() default -1;

: 해당 메소드 작업이 끝난 시점 기준으로 적용한 시간마다 실행 (단위 ms)
String fixedDelayString() default "";

: fixedDelay()와 기능은 동일하며 매개 값으로 문자열을 받습니다. (application.properties에 값을 넣고 사용 가능)

 

long fixedRate() default -1;

: 해당 메소드 작업이 시작한 시점 기준으로 적용한 시간마다 실행 (단위 ms)
String fixedRateString() default "";

: fixedRate()와 기능은 동일하며 매개 값으로 문자열을 받습니다.

 

long initialDelay() default -1;

: 지연 시간을 설정할 수 있습니다. (단위 ms) -> 최초 메소드 실행 시 지연 시간
String initialDelayString() default "";

: initialDelay()와 기능은 동일하며 매개 값으로 문자열을 받습니다.

package org.springframework.scheduling.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;

import org.springframework.scheduling.config.ScheduledTaskRegistrar;

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {

	String CRON_DISABLED = ScheduledTaskRegistrar.CRON_DISABLED;

	String cron() default "";

	String zone() default "";

	long fixedDelay() default -1;

	String fixedDelayString() default "";

	long fixedRate() default -1;

	String fixedRateString() default "";

	long initialDelay() default -1;

	String initialDelayString() default "";

	TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
}

4. fixedDelay, fixedDelayString

  • 해당 메소드 작업이 난 시점 기준으로 적용한 시간마다 실행됩니다.
  • 따라서 아래의 예시는 fixedDelay = 3000 + Thread.sleep(1000)로 sleep이 1초 추가됨으로써 메소드 작업 종료시간이 1초가 추가되어 4초마다 메소드가 실행된다고 볼 수 있습니다.
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

@Component
public class testScheduler {

    @Scheduled(fixedDelay = 3000)
    public void testPrintRepeat1() throws InterruptedException {
        DateTimeFormatter dtf =  DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
        System.out.println("스케쥴러 테스트(fixedDelay) " + LocalDateTime.now().format(dtf));
        Thread.sleep(1000);
    }
}

fixedDelay 테스트

5. fixedRate, fixedRateString

  • 해당 메소드 작업이 시작 시점 기준으로 적용한 시간마다 실행됩니다.
  • Thread.sleep(1000)이 존재하지만 메소드가 시작한 시점 기준이므로 3초 간격으로 메소드가 실행됩니다.
  • 적용한 fixedRate = 3000(3초) 값보다 sleep()을 크게 적용할 경우(3초 이상) sleep()의 값으로 반복 실행되게 됩니다.
  • EX) fixedRate = 3000(3초), sleep(10000) = 10초 간격으로 메소드 작업 반복 -> fixedRate < method execute time
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

@Component
public class testScheduler {

    @Scheduled(fixedRate = 3000)
    public void testPrintRepeat2() throws InterruptedException {
        DateTimeFormatter dtf =  DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
        System.out.println("스케쥴러 테스트(fixedRate) " + LocalDateTime.now().format(dtf));
        Thread.sleep(1000);
    }
}

fixedRate 결과

6. initialDelay, initialDelayString

  • 해당 메소드 최초 실행 시 지연시간을 적용합니다.
  • 아래의 예시는 5초 후에 3초 간격으로 반복 실행됩니다.
package com.test.api.scheduler;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

@Component
public class testScheduler {

    @Scheduled(fixedDelay = 3000, initialDelay = 5000)
    public void testPrintRepeat1() throws InterruptedException {
        DateTimeFormatter dtf =  DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
        System.out.println("스케쥴러 테스트(fixedDelay) " + LocalDateTime.now().format(dtf));
    }
}