• 欢迎访问本网站,技术教程,资源分享,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入东蓬莱!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏东部蓬莱吧

Spring 整合 Quartz 实现动态定时任务(定时修改服务器时间Demo)

后台开发 Jokul 1年前 (2020-05-18) 291次浏览 0个评论 扫描二维码

开发需求:

最近项目中需要用到定时任务的功能,虽然Spring 也自带了一个轻量级的定时任务Timer实现,但感觉不够灵活,功能也不够强大。项目需求动态修改定时任务参数以及定时时间问题,在考虑之后,决定整合更为专业的Quartz来实现定时任务功能。(Demo中删除了NTP方式时间更新工具类,请自行百度)

解决方案:

第一步:首先,当然是添加依赖的jar文件,我的项目是maven管理的,所以要添加如下依赖

<dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.2.1</version>
    </dependency>

第二步:编写参数实体对象

import java.util.Date;

/**
 * 时间配置实体类
 */
public class TimeConfig{
    private String id;
    private String ntpIp;
    private String ntpPort;
    private String timeZone;
    private String cronTime;
    private String operateMeans;
    private Date createTime;
    /** 任务名称 */
    private String jobName;
    /** 任务分组 */
    private String jobGroup;

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }

    public String getNtpIp() {
        return ntpIp;
    }

    public void setNtpIp(String ntpIp) {
        this.ntpIp = ntpIp;
    }

    public String getNtpPort() {
        return ntpPort;
    }

    public void setNtpPort(String ntpPort) {
        this.ntpPort = ntpPort;
    }

    public String getTimeZone() {
        return timeZone;
    }

    public void setTimeZone(String timeZone) {
        this.timeZone = timeZone;
    }

    public String getCronTime() {
        return cronTime;
    }

    public void setCronTime(String cronTime) {
        this.cronTime = cronTime;
    }

    public String getOperateMeans() {
        return operateMeans;
    }

    public void setOperateMeans(String operateMeans) {
        this.operateMeans = operateMeans;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getJobName() {
        return jobName;
    }

    public void setJobName(String jobName) {
        this.jobName = jobName;
    }

    public String getJobGroup() {
        return jobGroup;
    }

    public void setJobGroup(String jobGroup) {
        this.jobGroup = jobGroup;
    }
}

其中jobName和jobGroup两个参数是要在动态中作为任务判定使用的参数

第三步:任务运行入口,即Job实现类,在这里我把它看作工厂类(要实现Job接口)

import com.yosuntek.common.utils.SynSystemDateUtils;
import com.yosuntek.modules.sys.entity.TimeConfig;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.util.Map;

//@DisallowConcurrentExecution
public class TimeJob implements Job {
    @Override
    public void execute(JobExecutionContext job) throws JobExecutionException {
        TimeConfig timeConfig = (TimeConfig)job.getMergedJobDataMap().get("timeConfig");
        String name=timeConfig.getJobName();
        String ntpIp = timeConfig.getNtpIp();
        String ntpPort = timeConfig.getNtpPort();
        String timeZone = timeConfig.getTimeZone();
        System.out.println("定时器name:"+name
                +",ip:"+ntpIp
                +",port:"+ntpPort
                +",timeZone:"+timeZone
                +"正在运行。。。。。");
        int port = Integer.parseInt(ntpPort);
        Map<String, Object> map = SynSystemDateUtils.getNetTime(ntpIp, port, timeZone);
        String date = (String) map.get("dataStr_");
        String time = (String) map.get("timeStr_");
        SynSystemDateUtils.updateSysDateTime(date,time);
    }
}

本类中主要是通过实现Job接口,重写execute方法,然后通过get方法获取对应的参数对象,来进行一些定时执行的任务逻辑编写

第四步:编写调用接口实现修改,暂停,继续,删除等操作

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/sys/time")
public class TimeController{


    /**
     * 任务创建与更新(未存在的就创建,已存在的则更新)
     */
    @RequestMapping(value="/startQuartz")
    @ResponseBody
    public Map<String,Object> startQuartz(HttpServletRequest request){
        Map<String,Object> map = new HashMap<>();

        String jobName = "timeJobName";
        String jobGroup = "timeJobGroup";
        String ip = request.getParameter("ntpIp");
        String port = request.getParameter("ntpPort");
        String timeZone = request.getParameter("timeZone");
        String cronTime = request.getParameter("cronTime");

        TimeConfig timeConfig = new TimeConfig();
        timeConfig.setNtpIp(ip.trim());
        timeConfig.setNtpPort(port.trim());
        timeConfig.setTimeZone(timeZone.trim());
        timeConfig.setJobName(jobName.trim());
        timeConfig.setJobGroup(jobGroup.trim());

        int parseInt = Integer.parseInt(cronTime);
        String cron = CronUtil.createLoopCronExpression(1, parseInt);
        // 1、创建调度器Scheduler
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = null;
        try {
            scheduler = schedulerFactory.getScheduler();
            //获取触发器标识
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName.trim(), jobGroup.trim());
            //获取触发器trigger
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            if(null==trigger){//不存在任务
                //创建任务
                JobDetail jobDetail = JobBuilder.newJob(TimeJob.class)
                        .withIdentity(jobName.trim(), jobGroup.trim())
                        .build();
                jobDetail.getJobDataMap().put("timeConfig", timeConfig);
                //表达式调度构建器
                //这里的时间也可以通过页面传送过来。具体怎么写请看上一篇quartz介绍
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
                //按新的cronExpression表达式构建一个新的trigger
                trigger = TriggerBuilder.newTrigger()
                        .withIdentity(timeConfig.getJobName(), timeConfig.getJobGroup())
                        .startNow()//立即生效
                        .withSchedule(scheduleBuilder)
                        .build();
                scheduler.scheduleJob(jobDetail, trigger);
            }else{//存在任务
                // Trigger已存在,那么更新相应的定时设置
                //表达式调度构建器
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
                //按新的cronExpression表达式重新构建trigger
                trigger = trigger.getTriggerBuilder()
                        .withIdentity(triggerKey)
                        .startNow()//立即生效
                        .withSchedule(scheduleBuilder)
                        .build();
                //按新的trigger重新设置job执行
                scheduler.rescheduleJob(triggerKey, trigger);
            }
            //启动定时器
            scheduler.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        map.put("msg", "同步时间启动成功");
        map.put("code", 200);
        return map;
    }

    /**
     * 删除任务
     */
    @RequestMapping(value="/removeQuartz")
    public void deleteQuartz(HttpServletRequest request,String jobName,String jobGroup){
        JobKey jobKey = JobKey.jobKey(jobName.trim(), jobGroup.trim());
        System.out.println("删除"+jobName.trim()+"任务");
        // 1、创建调度器Scheduler
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = null;
        try {
            scheduler = schedulerFactory.getScheduler();
            scheduler.deleteJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * 暂停任务
     */
    @RequestMapping(value="/pauseQuartz")
    public void pauseQuartz(HttpServletRequest request,String jobName,String jobGroup){
        TimeConfig timeConfig = new TimeConfig();
        timeConfig.setJobGroup(jobGroup);
        timeConfig.setJobName(jobName);
        System.out.println(jobName+","+jobGroup);
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        // 1、创建调度器Scheduler
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = null;
        try {
            scheduler = schedulerFactory.getScheduler();
            scheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }


    /**
     * 恢复任务
     */
    @RequestMapping(value="/resumeQuartz")
    public void resumeQuartz(HttpServletRequest request,String jobName,String jobGroup){
        TimeConfig timeConfig = new TimeConfig();
        timeConfig.setJobGroup(jobGroup);
        timeConfig.setJobName(jobName);
        System.out.println(jobName+","+jobGroup);
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        // 1、创建调度器Scheduler
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = null;
        try {
            scheduler = schedulerFactory.getScheduler();
            scheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
}

东部蓬莱 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Spring 整合 Quartz 实现动态定时任务(定时修改服务器时间Demo)
喜欢 (0)
[支付宝]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址