-
[Quartz] SpringBoot 에서 동적으로 properties 파일 읽어 Cron 설정 변경Framework/Spring 2019. 5. 21. 16:40
SpringBoot 환경에서 스케쥴링을 설정하는 방법은 쉽다.
메인 함수 위에 @EnableScheduling 어노테이션을 달고
스케쥴링을 설정할 함수 위에@Scheduled(fixedDelayString ="600000") //600000은 ms 단위로 = 10분
혹은
@Scheduled(cron = "*/10 * * * * *") // Cron 표현식, 10초에 1번 실행
어노테이션을 달아주기만 하면 된다.
하지만 나는 Cron 표현식을 변경하여 설정해놓은 properties 파일을 변경하면
프로그램을 재시작하지 않아도 자동으로 적용되는 프로그램을 만들고 싶었다.
여기서 사용하게 된 것이
commons-configuration2 와
spring-boot-starter-quartz 이다.
commons-configuration2 는 주기적으로 파일을 읽어와서 편하게 값을 불러올 수 있다.
(commons-configuration2 2.3, commons-beanutils 1.9.3을 사용했다.
** application.properties (10초에 한 번 씩 실행)
cron.test=0/10 * * * * ?
** 파일에서 주기적으로 정보를 읽는 클래스
@Component public class ReloadBatchConfig { private ReloadingFileBasedConfigurationBuilder<>PropertiesConfiguration> builder; @PostConstruct // 초기화가 끝난 후 자동 실행 void init() { builder = new ReloadingFileBasedConfigurationBuilder<>(PropertiesConfiguration.class) .configure(new Parameters().fileBased().setFile(new File("./application.properties"))); // 설정 파일 위치를 적어준다. PeriodicReloadingTrigger configReloadingTrigger = new PeriodicReloadingTrigger( builder.getReloadingController(), null, 1, TimeUnit.SECONDS); //정보를 파일에서 리로드할 시간 설정 configReloadingTrigger.start(); } public Configuration getCompositeConfiguration() { try { return builder.getConfiguration(); //정보 읽음 } catch (ConfigurationException e) { e.printStackTrace(); } return null; } }
** 변경할 cron 표현식에 따라 주기적으로 실행할 메소드 (@Scheduled로 실행하는 메소드와 동일)
public class TestJob implements Job { // org.quartz.Job을 implements @Override public void execute(JobExecutionContext context) throws JobExecutionException { //실행할 코드 } }
** 파일에서 읽어온 표현식으로 메소드 실행주기를 바꿔주는 클래스
@Component @PropertySource("file:./config/batch.properties") public class SchedulerManager { private static final Logger logger = LoggerFactory.getLogger(SchedulerManager.class); private SchedulerFactory schedulerFactory; public static Scheduler scheduler; @Autowired private ReloadBatchConfig reloadConf; @Value("${cron.test}") private String testTime; //초기 실행 값 설정 public static String TestTime; //Cron 입력 시 Static만 가능 @PostConstruct public void init() { TestTime = testTime; //초기 실행할 스케줄러의 Trigger 생성 testTrigger = TriggerBuilder.newTrigger().withIdentity("testTriggerKey"). withIdentity(new TriggerKey("testTriggerKey")). withSchedule(CronScheduleBuilder.cronSchedule(TestTime)).build(); try { start(); } catch (SchedulerException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void start() throws SchedulerException{ schedulerFactory = new StdSchedulerFactory(); //여러 job을 실행 시 Scheduler도 따로 생성해준다. testScheduler = schedulerFactory.getScheduler(); testScheduler.start(); //실행할 Job JobDetail testJob = JobBuilder.newJob(TestJob.class).build(); //실행 testScheduler.scheduleJob(testJob, testTrigger); } //10초마다 batch.properties 읽어와서 배치 설정 바꿈 @Scheduled(fixedDelayString = "10000") public void get(){ public static String newTestTime = reloadConf.getCompositeConfiguration().getString("cron.test"); try { //파일의 값이 변경되었을 때만 수행 if (testcheduler != null && !testTime.equals(newTestTime)) { //변경될 cron 표현식을 쓸 새로운 Trigger 생성 CronTriggerImpl newTestTrigger = (CronTriggerImpl) testScheduler.getTrigger(testTrigger.getKey()); newReportTrigger.setCronExpression(newTestTime); //Trigger 값 변경 reportScheduler.rescheduleJob(testTrigger.getKey(), newTestTrigger); //주기 변경, 메소드 재실행된다. reportTime = newReportTime; //값 비교를 위한 초기화 } } catch (Exception e) { // TODO Auto-generated catch block logger.error("[Exception] Cron : " + e.getMessage()); } } }
프로그램 실행 중에 외부에 있는 application.properties 파일의 값을 변경하면
변경한 cron 표현식의 주기대로 메소드가 실행된다.
'Framework > Spring' 카테고리의 다른 글
[Springboot/BeanUtils] @Autowired null 문제 해결 (ApplicationContext로 Bean 주입) (0) 2019.05.24 [MVC] Controller - View : Cookie로 작업 종료 알림 (0) 2019.03.29 댓글