Spring Boot 配置 Quartz 定時任務

FH-Admin發表於2021-09-07

Quartz有四個核心概念:

Job:是一個介面,只定義一個方法 execute(JobExecutionContext context),在實現介面的 execute 方法中編寫所需要定時執行的 Job(任務)
Double slongitude = Double.valueOf(jobExecutionContext.getJobDetail().getJobDataMap().get(“slongitude”).toString());
JobDetail:Quartz 每次排程 Job 時,都重新建立一個 Job 例項,因此它不接受一個 Job 的例項,相反它接收一個 Job 實現類(JobDetail,描述 Job 的實現類及其他相關的靜態資訊,如 Job 名字、描述、關聯監聽器等資訊),以便執行時透過 newInstance() 的反射機制例項化 Job。
rigger:是一個類,描述觸發 Job 執行的時間觸發規則,主要有 SimpleTrigger 和 CronTrigger 這兩個子類。當且僅當需排程一次或者以固定時間間隔週期執行排程,SimpleTrigger 是最適合的選擇;而 CronTrigger 則可以透過 Cron 表示式定義出各種複雜時間規則的排程方案:如工作日週一到週五的 15:00 ~ 16:00 執行排程等。
Scheduler:排程器就相當於一個容器,裝載著任務和觸發器,該類是一個介面,代表一個 Quartz 的獨立執行容器,Trigger 和 JobDetail 可以註冊到 Scheduler 中,兩者在 Scheduler 中擁有各自的組及名稱,組及名稱是 Scheduler 查詢定位容器中某一物件的依據,Trigger 的組及名稱必須唯一,JobDetail 的組和名稱也必須唯一(但可以和 Trigger 的組和名稱相同,因為它們是不同型別的)。Scheduler 定義了多個介面方法,允許外部透過組及名稱訪問和控制容器中 Trigger 和 JobDetail。

1.匯入pom依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

2.開啟定時任務

@EnableScheduling註解

//java fhadmin.cn
@EnableScheduling
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

3.新建一個job

@Slf4j
public class MyJob implements Job {

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        try {

            executeTask(jobExecutionContext);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //java fhadmin.cn
    private static void executeTask(JobExecutionContext jobExecutionContext) throws SchedulerException {
//JobExecutionContext 類提供了排程應用的一些資訊;
//Job 執行時的資訊儲存在 JobDataMap 例項中。

        JobKey key = jobExecutionContext.getJobDetail().getKey();
        System.out.println(new Date()+"->"+key.toString()+"定時任務正在執行");

    }

}

4.構建JobDetail rigger ,把Trigger 和 JobDetail 可以註冊到 Scheduler 中

//fhrom fhadmin.cn
@Configuration
public class QuartzManager {

   // public static final String JOB1="job1";
   // public static final String GROUP1="group1";
    /**預設每個星期凌晨一點執行*/
    //public static final String DEFAULT_CRON="0 0 1 ? * L";
    /**預設5秒執行一次*/
   // public static final String DEFAULT_CRON="*/5 * * * * ?";

    /**
     * 任務排程
     */

     private Scheduler scheduler;

     @Bean
    public Scheduler scheduler() throws SchedulerException {
        SchedulerFactory schedulerFactoryBean = new StdSchedulerFactory();
        this.scheduler = schedulerFactoryBean.getScheduler();
        return schedulerFactoryBean.getScheduler();
    }
    /**
     * 開始執行定時任務
     */
    public void startJob(String name,String group,String time) throws SchedulerException {
        startJobTask(scheduler,name,group,time);
        scheduler.start();
    }
    /**
     * 啟動定時任務
     * @param scheduler
     */
    private void startJobTask(Scheduler scheduler,String  name ,String group,String time) throws SchedulerException {
                                                           //對於身份
        JobDetail jobDetail= JobBuilder.newJob(MyJob.class).withIdentity(name,group).build();
        System.out.println("jobDetail:-------------"+jobDetail);

        String DEFAULT_CRON="*/"+time+" * * * * ?";
        // SimpleScheduleBuilder  CronScheduleBuilder  用於構建Scheduler,定義任務排程的時間規則
        CronScheduleBuilder cronScheduleBuilder=CronScheduleBuilder.cronSchedule(DEFAULT_CRON);
        //觸發器
        CronTrigger cronTrigger=TriggerBuilder.newTrigger().withIdentity(name,group)
                .withSchedule(cronScheduleBuilder).build();
        scheduler.scheduleJob(jobDetail,cronTrigger);

    }

    /**
     * 獲取Job資訊
     * @param name
     * @param group
     */
    public String getjobInfo(String name,String group) throws SchedulerException {
        TriggerKey triggerKey=new TriggerKey(name,group);
        System.out.println("triggerKey:"+triggerKey);
        CronTrigger cronTrigger= (CronTrigger) scheduler.getTrigger(triggerKey);
        return String.format("time:%s,state:%s",cronTrigger.getCronExpression(),
                scheduler.getTriggerState(triggerKey).name());
    }

    /**
     * 修改任務的執行時間
     * @param name
     * @param group
     * @param cron cron表示式
     * @return
     * @throws SchedulerException
     */
    public boolean modifyJob(String name,String group,String cron) throws SchedulerException{
        Date date=null;
        TriggerKey triggerKey=new TriggerKey(name, group);
        CronTrigger cronTrigger= (CronTrigger) scheduler.getTrigger(triggerKey);
        String oldTime=cronTrigger.getCronExpression();
        if (!oldTime.equalsIgnoreCase(cron)){
            CronScheduleBuilder cronScheduleBuilder=CronScheduleBuilder.cronSchedule(cron);
            CronTrigger trigger=TriggerBuilder.newTrigger().withIdentity(name,group)
                    .withSchedule(cronScheduleBuilder).build();
            date=scheduler.rescheduleJob(triggerKey,trigger);
        }
        return date !=null;
    }

    /**
     * 暫停所有任務
     * @throws SchedulerException
     */
    public void pauseAllJob()throws SchedulerException{
        scheduler.pauseAll();
    }

    /**
     * 暫停某個任務
     * @param name
     * @param group
     * @throws SchedulerException
     */
    public void pauseJob(String name,String group)throws SchedulerException{
        JobKey jobKey=new JobKey(name,group);
        JobDetail jobDetail=scheduler.getJobDetail(jobKey);
        if (jobDetail==null) {
            return;
        }
        scheduler.pauseJob(jobKey);
    }

    /**
     * 恢復所有任務
     * @throws SchedulerException
     */
    public void resumeAllJob()throws SchedulerException{
        scheduler.resumeAll();
    }
    /**
     * 恢復某個任務
     */
    public void resumeJob(String name,String group)throws SchedulerException {
        JobKey jobKey=new JobKey(name,group);
        JobDetail jobDetail=scheduler.getJobDetail(jobKey);
        if (jobDetail==null) {
            return;
        }
        scheduler.resumeJob(jobKey);
    }

    /**
     * 刪除某個任務
     * @param name
     * @param group
     * @throws SchedulerException
     */
    public void deleteJob(String name,String group)throws SchedulerException{
        JobKey jobKey=new JobKey(name, group);
        JobDetail jobDetail=scheduler.getJobDetail(jobKey);
        if (jobDetail==null) {
            return;
        }
        scheduler.deleteJob(jobKey);
    }

}

5.編寫Controller

透過呼叫介面 可以開始定時任務 結束定時任務 獲取任務資訊

//fhadmin.cn
@RestController
@RequestMapping("/quartz")
public class ModifyCronController {

    @Autowired
    private QuartzManager quartzManager;
    @GetMapping("/modify")
    public String modify(@RequestParam("job")String job,   //job的名稱
                         @RequestParam("group")String group,//job的組
                         @RequestParam("time")String time   //執行定時任務的步長
     ) throws SchedulerException {

       // quartzManager.pauseJob(QuartzManager.JOB1,QuartzManager.GROUP1);
        quartzManager.startJob(job,group,time);
        String s = quartzManager.getjobInfo(job, group);
        System.out.println("job:"+s);

        return "ok";
    }
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章