SpringBoot動(dòng)態(tài)定時(shí)任務(wù)
其實(shí)SchedulingConfigurer實(shí)現(xiàn)方法很簡單,只需要實(shí)現(xiàn)SchedulingConfigurer并重寫configureTasks方法,在啟動(dòng)類必須加上@EnableScheduling注解即可。
@Configuration
@EnableScheduling
@Slf4j
public?class?RuleTask?implements?SchedulingConfigurer?{
????private?volatile?ScheduledTaskRegistrar?registrar;
????private?ConcurrentHashMap<Long,?ScheduledFuture<?>>?scheduledFutures?=?new?ConcurrentHashMap<>();
????private?ConcurrentHashMap<Long,?CronTask>?cronTasks?=?new?ConcurrentHashMap<>();
????@Override
????public?void?configureTasks(ScheduledTaskRegistrar?registrar)?{
????????registrar.setScheduler(Executors.newScheduledThreadPool(30));
????????this.registrar?=?registrar;
????}
????/**
?????*?刷新任務(wù)
?????*?cronList是數(shù)據(jù)庫查出來的定時(shí)任務(wù)列表
?????*?@param?ruleList
?????*/
????public?void?refresh(List<WarCron>?cronList)?{
????????//取消已經(jīng)刪除的任務(wù)
????????Set<Long>?cronIds?=?scheduledFutures.keySet();
????????for?(Long?cronId?:?cronIds)?{
????????????if?(!exists(cronList,?cronId))?{
????????????????scheduledFutures.get(cronId).cancel(false);
????????????}
????????}
????????if?(cronList?!=?null)?{
????????????for?(WarCron?warCron?:?cronList)?{
????????????????String?expression?=?warCron.getCron();
????????????????//定時(shí)任務(wù)已存在且表達(dá)式未發(fā)生變化時(shí)跳過
????????????????if?(scheduledFutures.containsKey(warCron.getCronId())?&&?cronTasks.get(warCron.getCronId()).getExpression().equals(expression))?{
????????????????????continue;
????????????????}
????????????????//如果執(zhí)行時(shí)間發(fā)生了變化,則取消當(dāng)前的定時(shí)任務(wù)
????????????????if?(scheduledFutures.containsKey(warCron.getCronId()))?{
????????????????????scheduledFutures.get(warCron.getCronId()).cancel(false);
????????????????????scheduledFutures.remove(warCron.getCronId());
????????????????????cronTasks.remove(warCron.getCronId());
????????????????}
????????????????CronTask?task?=?new?CronTask(
????????????????????????new?Runnable()?{
????????????????????????????@Override
????????????????????????????public?void?run()?{
????????????????????????????????System.out.println("------------定時(shí)任務(wù)--------------");
????????????????????????????}
????????????????????????},?warCron.getCron()
????????????????);
????????????????ScheduledFuture<?>?future?=?registrar.getScheduler().schedule(task.getRunnable(),?task.getTrigger());
????????????????cronTasks.put(warCron.getCronId(),?task);
????????????????scheduledFutures.put(warCron.getCronId(),?future);
????????????}
????????}
????}
???/**
?????*?判斷是否有該任務(wù)
?????*
?????*?@param?warCronList
?????*?@param?cronId
?????*?@return
?????*/
????private?boolean?exists(List<WarCron>?warCronList,?Long?cronId)?{
????????for?(WarCron?warCron?:?warCronList)?{
????????????if?(cronId.equals(warCron.getCronId()))?{
????????????????return?true;
????????????}
????????}
????????return?false;
????}
}
每次新增編輯刪除數(shù)據(jù)庫中的任務(wù)時(shí)都需刷新下任務(wù) 以達(dá)到任務(wù)的動(dòng)態(tài)變化
啟動(dòng)boot時(shí)也需執(zhí)行refresh方法;
/**
?*?@Author:?pandar
?*?@Date:?2021/3/12?0012?上午?11:57
?*?@Description:??項(xiàng)目啟動(dòng)后刷新定時(shí)任務(wù)
?*/
@Component
public?class?ApplicationRunnerConfig?implements?ApplicationRunner?{
????@Autowired
????private?RuleTask?ruleTask;
????@Autowired
????private?WarCronService?warCronService;
????@Override
????public?void?run(ApplicationArguments?args)?throws?Exception?{
????????List<WarCron>?warCronList?=?warCronService.selectWarCronAll();
????????ruleTask.refresh(ruleList);
????}
}
數(shù)據(jù)庫表結(jié)構(gòu)

評論
圖片
表情
