1. 메인 메소드가 존재하는 SpringBootApplication 클래스 에 @EnableScheduling //스케쥴러 사용 설정
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling //스케쥴러 사용 설정 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
2. ExampleScheduler
다음과 같이 사용
import java.util.Calendar; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import lombok.extern.slf4j.Slf4j; @Slf4j @Component public class ExampleScheduler { @Value("#{@isLocal}") private boolean local; /** 5초에 한번씩 실행 */ @Scheduled(cron ="#{@schedulerCronExample1}") public void schedule1() { log.info(" schedule1 동작하고 있음 {}, {} " ,local, Calendar.getInstance().getTime()); } }
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import lombok.extern.slf4j.Slf4j; @Slf4j @Component // 추가 @EnableAsync // 추가 public class ScheduleTest { /** * 해당 메서드 로직이 끝나는 시간 기준, milliseconds 간격으로 실행 * 이전 작업이 완료될 때까지 대기 */ @Scheduled(fixedDelay = 1000) public void scheduleFixedDelayTask() throws InterruptedException { log.info("Fixed delay task - {}", System.currentTimeMillis() / 1000); Thread.sleep(5000); } /** * 해당 메서드 로직이 시작하는 시간 기준, milliseconds 간격으로 실행 * 이전 작업이 완료될 때까지 다음 작업이 진행되지 않음 */ @Async // 병렬로 Scheduler 를 사용할 경우 @Async 추가 @Scheduled(fixedRate = 1000) public void scheduleFixedRateTask() throws InterruptedException { log.info("Fixed rate task - {}", System.currentTimeMillis() / 1000); Thread.sleep(5000); } /** * 설정된 initialDelay 시간(milliseconds) 후부터 fixedDelay 시간(milliseconds) 간격으로 실행 */ @Scheduled(fixedDelay = 1000, initialDelay = 5000) public void scheduleFixedRateWithInitialDelayTask() { long now = System.currentTimeMillis() / 1000; log.info("Fixed rate task with one second initial delay -{}", now); } /** * Cron 표현식을 사용한 작업 예약 * 초(0-59) 분(0-59) 시간(0-23) 일(1-31) 월(1-12) 요일(0-7) */ @Scheduled(cron = "0 15 10 15 * ?") public void scheduleTaskUsingCronExpression() { long now = System.currentTimeMillis() / 1000; log.info("schedule tasks using cron jobs - {}", now); } }
Setting information
fixedDelay
- 이전 작업이 종료된 후 설정시간(milliseconds) 이후에 다시 시작
- 이전 작업이 완료될 때까지 대기
fixedDelayString
- fixedDelay와 동일 하고 설정시간(milliseconds)을 문자로 입력하는 경우 사용
fixedRate
- 고정 시간 간격으로 시작
- 이전 작업이 완료될 때까지 다음 작업이 진행되지 않음
- 병렬 동작을 사용할 경우 @Async 추가
fixedRateString
- fixedRate와 동일 하고 설정시간(milliseconds)을 문자로 입력
initialDelay
- 설정된 initialDelay 시간 후부터 fixedDelay 시간 간격으로 실행
initialDelayString
- initialDelay와 동일 하고 설정시간(milliseconds)을 문자로 입력
cron
- Cron 표현식을 사용한 작업 예약
- cron = "* * * * * *"
- 첫번째 부터 초(0-59) 분(0-59) 시간(0-23) 일(1-31) 월(1-12) 요일(0-7)
zone
- zone = "Asia/Seoul"
- 미설정시 Local 시간대 사용
- A Time Zones
출처: https://data-make.tistory.com/699 [Data Makes Our Future:티스토리]
3. global properties 값들을 읽어와 환경별 설정
GlobalConfig
import java.util.Properties; import javax.annotation.PostConstruct; import org.apache.commons.lang3.ObjectUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.support.PropertiesLoaderUtils; import lombok.Data; import lombok.extern.slf4j.Slf4j; /** * global ~.properties 값을 읽어와 글로벌 변수설정하는 클래스 */ @Slf4j @Data public class GlobalConfig { @Autowired private ApplicationContext context; @Autowired private ResourceLoader resourceLoader; private String uploadFilePath; private String schedulerCronExample1; private boolean local; private boolean dev; private boolean prod; /** * @PostConstruct는 의존성 주입이 이루어진 후 초기화를 수행하는 메서드이다. * @PostConstruct가 붙은 메서드는 클래스가 service를 수행하기 전에 발생한다. * 이 메서드는 다른 리소스에서 호출되지 않는다해도 수행된다. @PostConstruct의 사용 이유 1) 생성자가 호출되었을 때, 빈은 초기화되지 않았음(의존성 주입이 이루어지지 않았음) 이럴 때 @PostConstruct를 사용하면 의존성 주입이 끝나고 실행됨이 보장되므로 빈의 초기화에 대해서 걱정할 필요가 없다. 2) bean 의 생애주기에서 오직 한 번만 수행된다는 것을 보장한다. (어플리케이션이 실행될 때 한번만 실행됨) 따라서 bean이 여러 번 초기화되는 걸 방지할 수 있다 여기서는, ApplicationContext, ResourceLoader 가 의존성 주입이 완료되었는지에 대해 염려할 필요가 없다. */ @PostConstruct public void init(){ log.info("GlobalConfig-init" ); String[] activeProfiles =context.getEnvironment().getActiveProfiles(); String activeProfile="local"; // 기본위치 local if(ObjectUtils.isNotEmpty(activeProfiles)) { activeProfile=activeProfiles[0]; } String resourcePath=String.format("classpath:globals/global-%s.properties", activeProfile); try { Resource resource=resourceLoader.getResource(resourcePath); Properties properties=PropertiesLoaderUtils.loadProperties(resource); this.uploadFilePath=properties.getProperty("uploadFile.path"); this.schedulerCronExample1 =properties.getProperty("scheduler.cron.example1"); this.local=activeProfile.equals("local"); this.dev=activeProfile.equals("dev"); this.prod=activeProfile.equals("prod"); }catch (Exception e) { log.error("e", e); } } public String getUploadFilePath() { return uploadFilePath; } }
SchedulerCronConfiguration
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import kr.net.macaronics.configuration.GlobalConfig; @Configuration public class SchedulerCronConfiguration { /** * global ~.properties 값을 읽어와 글로벌 변수설정하는 클래스 */ @Autowired private GlobalConfig config; /** global properties 값을 가져와 전역 사용할 수 있도록 빈등록 * */ @Bean public String schedulerCronExample1() { return config.getSchedulerCronExample1(); } @Bean public boolean isLocal() { return config.isLocal(); } @Bean public boolean isDev() { return config.isDev(); } @Bean public boolean isProd() { return config.isProd(); } }
WebMvcConfig 에 GlobalConfig 등록
@Bean public GlobalConfig globalConfig(){ return new GlobalConfig(); }
스프링부트 프로퍼티 로컬, 개발, 운영 설정값 클래스로 관리 @PostConstruct 어노테이션 활용
소스 :
댓글 ( 4)
댓글 남기기