[SPRING] @Scheduled 주석을 사용하여 시작된 예약 된 작업을 중지하는 방법은 무엇입니까?
SPRING@Scheduled 주석을 사용하여 시작된 예약 된 작업을 중지하는 방법은 무엇입니까?
Spring Framework의 @Scheduled 주석을 사용하여 간단한 예약 된 작업을 만들었습니다.
@Scheduled(fixedRate = 2000)
public void doSomething() {}
이제 더 이상 필요하지 않을 때이 작업을 중단하고 싶습니다.
이 방법의 시작 부분에 하나의 조건 플래그를 확인하는 대안이있을 수 있지만이 방법의 실행은 중단되지 않습니다.
@Scheduled 작업을 멈추기 위해 Spring이 제공하는 것이 있습니까?
해결법
-
==============================
1.ScheduledAnnotationBeanPostProcessor를 제공하고 스케줄링을 중지해야하는 bean에 대해 postProcessBeforeDestruction (Object bean, String beanName)을 명시 적으로 호출하십시오.
ScheduledAnnotationBeanPostProcessor를 제공하고 스케줄링을 중지해야하는 bean에 대해 postProcessBeforeDestruction (Object bean, String beanName)을 명시 적으로 호출하십시오.
private final Map<Object, ScheduledFuture<?>> scheduledTasks = new IdentityHashMap<>(); @Scheduled(fixedRate = 2000) public void fixedRateJob() { System.out.println("Something to be done every 2 secs"); } @Bean public TaskScheduler poolScheduler() { return new CustomTaskScheduler(); } class CustomTaskScheduler extends ThreadPoolTaskScheduler { @Override public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period) { ScheduledFuture<?> future = super.scheduleAtFixedRate(task, period); ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task; scheduledTasks.put(runnable.getTarget(), future); return future; } @Override public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Date startTime, long period) { ScheduledFuture<?> future = super.scheduleAtFixedRate(task, startTime, period); ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task; scheduledTasks.put(runnable.getTarget(), future); return future; } }
Bean에 대한 스케줄링을 중지해야 할 때 맵을 검색하여 해당 Future를 가져 와서 명시 적으로 취소 할 수 있습니다.
-
==============================
2.이 질문에는 다소 모호한 점이 있습니다.
이 질문에는 다소 모호한 점이 있습니다.
내 최고의 추측은 복구 가능한 방식으로 동일한 앱에서 발생할 수있는 조건을 사용하여 작업을 종료하려고하는 것입니다. 나는이 가정에 기초하여 대답하려고 노력할 것이다.
이것은 내가 생각할 수있는 가장 간단한 가능한 해결책이지만, 중첩 된 if보다는 조기 복귀와 같은 몇 가지 개선을 할 것입니다.
@Component public class SomeScheduledJob implements Job { private static final Logger LOGGER = LoggerFactory.getLogger(SomeScheduledJob.class); @Value("${jobs.mediafiles.imagesPurgeJob.enable}") private boolean imagesPurgeJobEnable; @Override @Scheduled(cron = "${jobs.mediafiles.imagesPurgeJob.schedule}") public void execute() { if(!imagesPurgeJobEnable){ return; } Do your conditional job here... }
위 코드의 속성
jobs.mediafiles.imagesPurgeJob.enable=true or false jobs.mediafiles.imagesPurgeJob.schedule=0 0 0/12 * * ?
-
==============================
3.얼마 전 필자는 모든 구성 요소가 새로운 예약 된 작업을 만들거나 스케줄러 (모든 작업)를 중지 할 수 있어야한다는 것을 내 프로젝트에서 요구했습니다. 그래서 나는 이런 것을했다.
얼마 전 필자는 모든 구성 요소가 새로운 예약 된 작업을 만들거나 스케줄러 (모든 작업)를 중지 할 수 있어야한다는 것을 내 프로젝트에서 요구했습니다. 그래서 나는 이런 것을했다.
@Configuration @EnableScheduling @ComponentScan @Component public class CentralScheduler { private static AnnotationConfigApplicationContext CONTEXT = null; @Autowired private ThreadPoolTaskScheduler scheduler; public static CentralScheduler getInstance() { if (!isValidBean()) { CONTEXT = new AnnotationConfigApplicationContext(CentralScheduler.class); } return CONTEXT.getBean(CentralScheduler.class); } @Bean public ThreadPoolTaskScheduler taskScheduler() { return new ThreadPoolTaskScheduler(); } public void start(Runnable task, String scheduleExpression) throws Exception { scheduler.schedule(task, new CronTrigger(scheduleExpression)); } public void start(Runnable task, Long delay) throws Exception { scheduler.scheduleWithFixedDelay(task, delay); } public void stopAll() { scheduler.shutdown(); CONTEXT.close(); } private static boolean isValidBean() { if (CONTEXT == null || !CONTEXT.isActive()) { return false; } try { CONTEXT.getBean(CentralScheduler.class); } catch (NoSuchBeanDefinitionException ex) { return false; } return true; } }
그래서 나는 같은 것을 할 수있다.
Runnable task = new MyTask(); CentralScheduler.getInstance().start(task, 30_000L); CentralScheduler.getInstance().stopAll();
몇 가지 이유로 동시성에 대해 걱정할 필요없이이를 수행했음을 명심하십시오. 그렇지 않으면 약간의 동기화가 있어야합니다.
-
==============================
4.다음은 예약 된 모든 실행중인 작업을 중지하고 시작하고 나열 할 수있는 예제입니다.
다음은 예약 된 모든 실행중인 작업을 중지하고 시작하고 나열 할 수있는 예제입니다.
@RestController @RequestMapping("/test") public class TestController { private static final String SCHEDULED_TASKS = "scheduledTasks"; @Autowired private ScheduledAnnotationBeanPostProcessor postProcessor; @Autowired private ScheduledTasks scheduledTasks; @Autowired private ObjectMapper objectMapper; @GetMapping(value = "/stopScheduler") public String stopSchedule(){ postProcessor.postProcessBeforeDestruction(scheduledTasks, SCHEDULED_TASKS); return "OK"; } @GetMapping(value = "/startScheduler") public String startSchedule(){ postProcessor.postProcessAfterInitialization(scheduledTasks, SCHEDULED_TASKS); return "OK"; } @GetMapping(value = "/listScheduler") public String listSchedules() throws JsonProcessingException{ Set<ScheduledTask> setTasks = postProcessor.getScheduledTasks(); if(!setTasks.isEmpty()){ return objectMapper.writeValueAsString(setTasks); }else{ return "No running tasks !"; } }
}
-
==============================
5.spring 프로세스가 Scheduled 일 때,이 주석으로 주석 처리 된 각 메소드를 반복하고 다음 소스가 보여주는 것처럼 Bean별로 태스크를 구성합니다.
spring 프로세스가 Scheduled 일 때,이 주석으로 주석 처리 된 각 메소드를 반복하고 다음 소스가 보여주는 것처럼 Bean별로 태스크를 구성합니다.
private final Map<Object, Set<ScheduledTask>> scheduledTasks = new IdentityHashMap<Object, Set<ScheduledTask>>(16);
반복되는 예약 된 작업을 취소하려는 경우 다음과 같이 할 수 있습니다 (여기 내 repo에서 실행 가능한 데모).
@Autowired private ScheduledAnnotationBeanPostProcessor postProcessor; @Autowired private TestSchedule testSchedule; public void later() { postProcessor.postProcessBeforeDestruction(test, "testSchedule"); }
이 Bean의 예약 된 작업을 찾아서 하나씩 취소합니다. 주목해야 할 점은 현재 실행중인 메소드 (postProcess Before Destruction 소스가 보여 주듯이)를 멈추게 할 것입니다.
synchronized (this.scheduledTasks) { tasks = this.scheduledTasks.remove(bean); // remove from future running } if (tasks != null) { for (ScheduledTask task : tasks) { task.cancel(); // cancel current running method } }
from https://stackoverflow.com/questions/44644141/how-to-stop-a-scheduled-task-that-was-started-using-scheduled-annotation by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring MVC에서 PUT과 DELETE 메소드 사용하기 (0) | 2018.12.19 |
---|---|
[SPRING] XML없이 Spring 4에서 EhCache 사용하기 (0) | 2018.12.19 |
[SPRING] 최대 절전 모드, 봄, JPA 및 격리 - 사용자 정의 격리는 지원되지 않습니다. (0) | 2018.12.19 |
[SPRING] Spring / Rest @PathVariable 문자 인코딩 (0) | 2018.12.19 |
[SPRING] JsonIdentityInfo가 포함 된 JavaScript에서 Jackson 객체를 deserialize합니다. (0) | 2018.12.19 |