Spring @Scheduled(cron = "...") 雖然簡單,但 Cron 表達式寫死在代碼中,無法滿足「運行時動態調整排程」的需求。本文展示如何結合 Quartz Scheduler,通過 SchedulingConfigurer + Trigger 實現 Cron 表達式的動態更新,並提供 REST API 供外部調用修改。
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
</dependency>
cron:
pattern: "0/1 * * * * ?" # 預設每秒執行一次
public class DynamicScheduledTask implements SchedulingConfigurer {
@Value("${cron.pattern}")
private String pattern; // 運行時可變更
public void setCron(String cron) { this.pattern = cron; }
@Override
public void configureTasks(ScheduledTaskRegistrar registrar) {
registrar.addTriggerTask(
this::doBiz, // 執行邏輯
triggerContext -> {
// 每次執行前重新解析最新 pattern
CronTrigger trigger = new CronTrigger(pattern);
return trigger.nextExecutionTime(triggerContext);
}
);
}
protected void doBiz() { System.out.println("do biz..."); }
}
關鍵點:Trigger 的 nextExecutionTime 每次調度前都會被調用,此處動態構建 CronTrigger 即可實現熱更新。
@SpringBootApplication
@EnableScheduling
public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
@Component
public class UserDynamicJob extends DynamicScheduledTask {
@Autowired private IUserService userService;
@Override
public void doBiz() {
try {
User user = userService.selectOne(new HashMap<>());
System.out.println("Dynamic job exec: " + user);
} catch (DataNotFoundException e) { e.printStackTrace(); }
}
}
do biz...POST /api/cron?cron=0/10 * * * * ?JobDetail/Trigger API 實現任務暫停/恢復/刪除此方案輕量、無侵入,適合中小型專案快速接入動態排程需求。