springboot2 集成quatz web動態管理

原理不做介紹了,可以看這位大神的:https://www.cnblogs.com/zhangchengzhangtuo/p/5705672.html

1、maven(sql用作quatz的web操作持久化)

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>

2、quatz核心代碼(只放核心代碼,具體代碼最後有地址鏈接)

①quatz配置

package com.quartz.config;

import org.mybatis.spring.annotation.MapperScan;
import org.quartz.Scheduler;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import java.io.IOException;
import java.util.Properties;

/**
 * @description: Scheduler配置類
 * @author: zyj
 * @create: 2020-01-02 10:20
 **/
@Configuration
@MapperScan({"com.quartz.**.dao"})
public class SchedulerConfig {

    @Bean(name="SchedulerFactory")
    public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setQuartzProperties(quartzProperties());
        return factory;
    }

    @Bean
    public Properties quartzProperties() throws IOException {
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
        //在quartz.properties中的屬性被讀取並注入後再初始化對象
        propertiesFactoryBean.afterPropertiesSet();
        return propertiesFactoryBean.getObject();
    }

    /**
     * quartz初始化監聽器
     * 這個監聽器可以監聽到工程的啓動,在工程停止再啓動時可以讓已有的定時任務繼續進行。
     * @return
     */
    @Bean
    public QuartzInitializerListener executorListener() {
        return new QuartzInitializerListener();
    }

    /**
     *
     *通過SchedulerFactoryBean獲取Scheduler的實例
     */

    @Bean(name="Scheduler")
    public Scheduler scheduler() throws IOException {
        return schedulerFactoryBean().getScheduler();
    }

}

②quatz執行類

package com.quartz.util;

import com.quartz.dao.QuartzDao;
import com.quartz.entity.AppQuartz;
import com.quartz.entity.JobAndTrigger;
import com.quartz.service.BaseJob;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.util.List;

import static org.quartz.DateBuilder.futureDate;

/**
 * @description:
 * @author: zyj
 * @create: 2020-01-03 09:49
 **/
@Component
public class QuartzUtil {

    Logger logger = LoggerFactory.getLogger(QuartzUtil.class);

    @Autowired
    private QuartzDao quartzDao;

    @Autowired
    private DateUnit dateUnit;


    //加入Qulifier註解,通過名稱注入bean
    @Autowired
    @Qualifier("Scheduler")
    private Scheduler scheduler;

    public List<JobAndTrigger> jobList(){
        try {
            return quartzDao.jobAndTriggerList();
        }catch (Exception e){
            logger.error("查詢定時任務列表失敗", e);
        }

        return null;
    }

    /**
    * @Description: 新建一個任務
    * @Param: [appQuartz]
    * @return: java.lang.String
    * @Author: zyj
    * @Date: 2020/1/3
    */
    public String addJob(AppQuartz appQuartz) throws Exception  {
        if ("".equals(appQuartz.getJobGroup()) || "".equals(appQuartz.getJobName()) || "".equals(appQuartz.getJobClassName()) || "".equals(appQuartz.getCronExpression())) {
            return "沒有接收到參數,請檢查";
        }
        if (appQuartz.getTimeType() == null) {
            return addCronJob(appQuartz);
        }
        return addSimpleJob(appQuartz);
    }

    /**
    * @Description: 有參數job
    * @Param: [appQuartz]
    * @return: java.lang.String
    * @Author: zyj
    * @Date: 2020/1/3
    */
    public String addCronJob(AppQuartz appQuartz) throws Exception {

        // 啓動調度器
        scheduler.start();
        String className =  appQuartz.getJobClassName().trim();
        String [] classNames = className.split("\\.");
        //構建job信息
        JobDetail jobDetail = JobBuilder.newJob(getClass(className).getClass())
                .withDescription(appQuartz.getDesciption())
                .withIdentity(appQuartz.getJobName(), appQuartz.getJobGroup())
                .build();

        //表達式調度構建器(即任務執行的時間)
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(appQuartz.getCronExpression());
        //按新的cronExpression表達式構建一個新的trigger
        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withDescription(appQuartz.getDesciption())
                .withIdentity(classNames[classNames.length-1], classNames[classNames.length-2])
                .withSchedule(scheduleBuilder)
                .build();

        //傳遞參數
        if(appQuartz.getInvokeParam()!=null && !"".equals(appQuartz.getInvokeParam())) {
            trigger.getJobDataMap().put("invokeParam",appQuartz.getInvokeParam());
        }
        try {
            scheduler.scheduleJob(jobDetail, trigger);
            return "success";
        } catch (SchedulerException e) {
            logger.error("創建定時任務失敗", e);
            return e.getMessage();
        }
    }

    /**
    * @Description:  暫停job
    * @Param: [jobName 任務名, jobGroupName 任務組]
    * @return: void
    * @Author: zyj
    * @Date: 2020/1/3
    */
    public void jobPause(String jobName, String jobGroupName) throws Exception {
        scheduler.pauseJob(JobKey.jobKey(jobName, jobGroupName));
    }



    /**
    * @Description: 恢復任務
    * @Param: [jobName 任務名, jobGroupName 任務組]
    * @return: void
    * @Author: zyj
    * @Date: 2020/1/3
    */
    public void jobResume(String jobName, String jobGroupName) throws SchedulerException {
        scheduler.resumeJob(JobKey.jobKey(jobName, jobGroupName));
    }


    /**
    * @Description: 刪除定時任務
    * @Param: [jobName 任務名稱, jobGroupName任務組]
    * @return: void
    * @Author: zyj
    * @Date: 2020/1/3
    */
    public void jobDelete(String jobName, String jobGroupName) throws Exception {
        scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroupName));
        scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroupName));
        scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));
    }


    /**
    * @Description:  修改任務
    * @Param: [appQuartz]
    * @return: java.lang.String
    * @Author: zyj
    * @Date: 2020/1/3
    */
    public void modifyJob(AppQuartz appQuartz) throws Exception {
        jobreschedule(appQuartz.getTriggerName(), appQuartz.getTriggerGroup(), appQuartz.getCronExpression());
    }


    /**
    * @Description: 根據tigger修改任務
    * @Param: [jobName, jobGroupName, cronExpression]
    * @return: void
    * @Author: zyj
    * @Date: 2020/1/14
    */
    public void jobreschedule(String triggerName, String triggerGroup, String cronExpression) throws Exception {
        TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
        // 表達式調度構建器
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);

        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

        // 按新的cronExpression表達式重新構建trigger
        CronTrigger triggerNew = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

        // 按新的trigger重新設置job執行
        scheduler.rescheduleJob(triggerKey, triggerNew);

    }

    /**
    * @Description:  轉化爲time格式的定時任務
    * @Param: [appQuartz]
    * @return: java.lang.String
    * @Author: zyj
    * @Date: 2020/1/14
    */
    public String addSimpleJob(AppQuartz appQuartz) throws Exception {

        // 啓動調度器
        scheduler.start();
        String className =  appQuartz.getJobClassName().trim();
        String [] classNames = className.split("\\.");
        //構建job信息
        JobDetail jobDetail = JobBuilder.newJob(getClass(className).getClass())
                .withDescription(appQuartz.getDesciption())
                .withIdentity(appQuartz.getJobName(), appQuartz.getJobGroup())
                .build();

        DateBuilder.IntervalUnit verDate = dateUnit.verification(appQuartz.getTimeType());
        SimpleTrigger simpleTrigger = (SimpleTrigger) TriggerBuilder.newTrigger()
                .withDescription(appQuartz.getDesciption())
                .withIdentity(classNames[classNames.length-1], classNames[classNames.length-2])
                .startAt(futureDate(Integer.parseInt(appQuartz.getCronExpression()), verDate))
                .forJob(appQuartz.getJobClassName(), appQuartz.getJobGroup())
                .build();

        //傳遞參數
        if(appQuartz.getInvokeParam()!=null && !"".equals(appQuartz.getInvokeParam())) {
            simpleTrigger.getJobDataMap().put("invokeParam",appQuartz.getInvokeParam());
        }
        try {
            scheduler.scheduleJob(jobDetail, simpleTrigger);
            return "success";
        } catch (SchedulerException e) {
            logger.error("創建定時任務失敗", e);
            return e.getMessage();
        }
    }


    /**
     * 根據類名稱,通過反射得到該類,然後創建一個BaseJob的實例。
     * 由於自己的Job類都實現了BaseJob,
     * 所以這裏不需要我們手動去判斷。這裏涉及到了一些java多態調用的機制
     *
     * @param classname
     * @return
     * @throws Exception
     */
    public static BaseJob getClass(String classname) throws Exception {
        Class<?> class1 = Class.forName(classname);
        return (BaseJob) class1.newInstance();
    }

}

源碼地址:https://gitee.com/kuang_wu/my-springboot

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章