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)
댓글 남기기