반응형
보통 스케줄러를 구성할때 크론탭으로 일정시간을 하드코딩으로 넣거나 프로퍼티 또는 db에서 가져와서 세팅하는 형태로 많이 구현을 하는데, 요구사항으로 입력에 따라 운용중인 시스템에서 스케줄러 동작 시간이 변경되도록 구현이 되어야 했다.
자바8 이상 기준으로 작성되었습니다.
ThreadPoolTaskScheduler 클래스를 통해 구현을 진행했다.
동적 스케줄러 구성하기
DynamicChangeScheduler.java
import java.time.LocalDateTime;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
@Component
public class DynamicChangeScheduler {
private ThreadPoolTaskScheduler scheduler;
private String cron = "*/2 * * * * *";
public void startScheduler() {
scheduler = new ThreadPoolTaskScheduler();
scheduler.initialize();
// scheduler setting
scheduler.schedule(getRunnable(), getTrigger());
}
public void changeCronSet(String cron) {
this.cron = cron;
}
public void stopScheduler() {
scheduler.shutdown();
}
private Runnable getRunnable() {
// do something
return () -> {
System.out.println(LocalDateTime.now().toString());
};
}
private Trigger getTrigger() {
// cronSetting
return new CronTrigger(cron);
}
@PostConstruct
public void init() {
startScheduler();
}
@PreDestroy
public void destroy() {
stopScheduler();
}
}
일반적으로 @Scheduled 어노테이션으로 크론탭이나 주기시간을 입력하여 동작하도록 처리하는데, ThreadPoolTaskScheduler를 통해 스케줄러를 생성하고 run을 시키는 형태로 구현하였다.
프로젝트가 구동하자마자 동작을 시키기 위해 postContruct 어노테이션 메소드에 startScheduler메소드 실행하여 스케줄러가 바로 동작하도록 하였다.
getRunnable 메소드에 정의된 실행 동작으로 인해 처음엔 2초마다 현재 시간을 찍어대기 시작한다.
view페이지에서 입력이 들어오면 시간을 바꾸도록 하였다.
AdminController.java
import java.util.HashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import egovframework.srok.sheduler.DynamicChangeScheduler;
@Controller
public class AdminController {
@Autowired
DynamicChangeScheduler ps;
@RequestMapping(value="/setting.do")
public ModelAndView setting() throws Exception{
ModelAndView mv = new ModelAndView();
mv.setViewName("admin/setting");
return mv;
}
@RequestMapping(value="/updateScheduler.do")
public @ResponseBody HashMap<Object, Object> updateScheduler(@RequestParam HashMap<Object, Object> params) throws Exception{
ps.stopScheduler();
Thread.sleep(1000);
ps.changeCronSet((String) params.get("cron"));
ps.startScheduler();
HashMap<Object, Object> res = new HashMap<Object, Object>();
res.put("res", "success");
return res;
}
@RequestMapping(value="/pauseScheduler.do")
public @ResponseBody HashMap<Object, Object> pauseScheduler(@RequestParam HashMap<Object, Object> params) throws Exception{
ps.stopScheduler();
HashMap<Object, Object> res = new HashMap<Object, Object>();
res.put("res", "success");
return res;
}
}
admin/setting.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>스케줄러 테스트</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<h1>스케줄러 동작 시간 변경 테스트</h1>
<input type="text" id="cronTab">
<br/>
<a href="javascript:void(0);" id="changeTest">스케줄러 동작 시간 변경</a>
<a href="javascript:void(0);" id="pauseTest">스케줄러 중지</a>
</body>
<script>
$(function(){
$(document).on("click", "#changeTest", function(){
$.ajax({
url: 'updateScheduler.do',
type: 'POST',
data: {cron: $("#cronTab").val()},
success: function (data) {
if(data.res == "success"){
alert("스케줄러 동작 시간이 변경되었습니다.");
location.reload();
}
},
error: function (error) {
console.log(error)
}
});
}).on("click", "#pauseTest", function(){
$.ajax({
url: 'pauseScheduler.do',
type: 'POST',
data: '',
success: function (data) {
if(data.res == "success"){
alert("스케줄러가 멈췄습니다.");
location.reload();
}
},
error: function (error) {
console.log(error)
}
});
});
});
</script>
</html>
input 박스에 크론탭형태로 데이터를 넣고 시간 변경을 하면 변경된 크론 형태로 스케줄러가 동작하고, 중지를 누르면 기존에 동작하던 스케줄러가 멈추도록 구성하였다.
반응형
'WEB > Spring' 카테고리의 다른 글
egov - 전자정부 프레임워크 및 톰캣, 자바 버전업하기(error 대처 - ASM ClassReader failed to parse class file) (0) | 2021.08.04 |
---|---|
Spring - 구동 중인 서버의 절대경로 구하기(getReadlPath) (0) | 2021.07.02 |
.m2 저장소 변경하기 및 스프링프로젝트 로드 오류 - org.apache.catalina.LifecycleException: 구성요소 (0) | 2021.05.13 |
Spring - 이미지(Image) 파일 byteArray로 전달하고 javascript base64 이미지 표현하기 (0) | 2021.01.29 |
SpringBoot - 스프링부트에서 스케줄러 사용하기 (0) | 2021.01.19 |