SSM的quartz动态定时器

Controller层:

package com.smartteam.controller;

import com.smartteam.controller.BaseController;
import com.smartteam.service.SampleTryEntryService;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author XiaoDeng
 * @since 2019-08-06
 */
@Api(tags = "动态定时器")
@RestController
@RequestMapping("/sampleTry")
public class SampleTryController extends BaseController {

    @Autowired
    private SampleTryEntryService sampleTryEntryService;

    /**
     * 逻辑处理
     */
    public void sampleTryEntity(){
        // 逻辑处理之后启动定时任务
        sampleTryEntryService.scrhySendMessage();
    }

}

SampleTryEntryService层:

package com.smartteam.service;

import com.baomidou.mybatisplus.extension.service.IService;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author XiaoDeng
 * @since 2019-08-06
 */
public interface SampleTryEntryService extends IService<SampleTryEntry> {

    /**
     * 逻辑处理之后启动定时任务
     */
    void scrhySendMessage();
}

SampleTryEntryServiceImpl层:

package com.smartteam.service.impl;

import com.smartteam.common.DateUtil;
import com.smartteam.common.quartz.CronUtils;
import com.smartteam.common.quartz.QuartzManager;
import com.smartteam.mapper.erp.SampleTryEntryMapper;
import com.smartteam.service.SampleTryEntryService;
import com.smartteam.vo.quartz.QuartzVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.quartz.SchedulerException;
import org.springframework.stereotype.Service;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author XiaoDeng
 * @since 2019-08-06
 */
@Service
public class SampleTryEntryServiceImpl extends ServiceImpl<SampleTryEntryMapper, SampleTryEntry> implements SampleTryEntryService {

    /**
     * 判断定时任务是否开启
     */
    public boolean startQuartz = false;
    /**
     * new一个定时器
     */
    QuartzManager quartz = new QuartzManager();
    /**
     * 保存定时任务要用到的信息
     */
    public static List<Map<String, Object>> scymaps = new ArrayList<>();

    /**
     * 逻辑处理之后启动定时任务
     */
    @Override
    public void scrhySendMessage() {
        // 把计划回收日期小于当前日期的数据的发送消息状态设置为1(防止服务断掉的时候,导致发送消息失败)
        QueryWrapper<SampleTryEntry> wrapper = new QueryWrapper<>();
        wrapper.eq("SENDOUT", 0);
        wrapper.lt("FSAMPLERECOVERYD", new Date());
        List<SampleTryEntry> tryEntries = list(wrapper);
        for (SampleTryEntry entry : tryEntries) {
            entry.setSendout(1);
            updateEntry(entry);
        }
        // 获取定时任务要用到的信息
        List<Map<String, Object>> maps = this.baseMapper.trialWearerData();
        scymaps = maps;
        // 移除定时任务
        if(startQuartz == true){
            try {
                quartz.removeJob("定时任务提醒", "System");
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }else{
            // 开启定时任务
            quartz.start();
            startQuartz = true;
        }
        if(maps.size() > 0){
            // 时间都是一样的:比如有6行数据,每行数据FSAMPLERECOVERYD的值都一样
            String fsamplerecoveryd = maps.get(0).getOrDefault("FSAMPLERECOVERYD", "").toString();
            // 把日期转化为cron表达式
            String crontime = CronUtils.getCron(DateUtil.parseTime(fsamplerecoveryd, "yyyy-MM-dd HH:mm:ss"));
            // 添加定时任务
            QuartzVo vo = new QuartzVo();
            vo.setClassName("com.smartteam.quartz.YygQuartzJob");
            vo.setJobName("定时任务提醒");
            vo.setJobGroup("System");
            vo.setCronExpression(crontime);
            quartz.addJob(vo);
        }
    }

}

CronUtils类:日期转换cron表达式

package com.smartteam.common.quartz;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;

/**
 * 日期转换cron表达式
 * @author Administrator
 *
 */
public class CronUtils {

    //"ss mm HH dd MM ? yyyy"
    private static final SimpleDateFormat sdf = new SimpleDateFormat("ss mm HH dd MM ?");

    /***
     *  功能描述:日期转换cron表达式
     * @param date
     * @return
     */
    public static String formatDateByPattern(Date date) {
        String formatTimeStr = null;
        if (Objects.nonNull(date)) {
            formatTimeStr = sdf.format(date);
        }
        return formatTimeStr;
    }

    /***
     * convert Date to cron, eg "0 07 10 15 1 ?"
     * @param date  : 时间点
     * @return
     */
    public static String getCron(Date date) {
        return formatDateByPattern(date);
    }
}

定时任务管理器QuartzManager:

package com.smartteam.common.quartz;

import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;

import com.smartteam.vo.quartz.QuartzVo;

/**
 * 定时任务管理器
 * @author Administrator
 *
 */
public class QuartzManager {

    private Logger log = LogManager.getLogger(QuartzManager.class);

    private Scheduler scheduler = null;

    /**
     * 初始化调度器
     */
    public QuartzManager() {
        try {
            scheduler = new StdSchedulerFactory().getScheduler();
            log.info("初始化调度器 ");
        } catch (SchedulerException ex) {
            log.error("初始化调度器=> [失败]:" + ex.getLocalizedMessage());
        }
    }
    //初始化启动任务
    public void initJob(){
        this.start();
    }

     /**
      * 添加定时任务<br/>
      * className:时间到了要执行的类名:com.information.quartz.YygQuartzJob<br/>
      * jobName:自定义任务名:定时任务提醒<br/>
      * jobGroup:自定义组名:System<br/>
      * cronExpression:cron定时表达式:00 16 18 18 06 ?<br/>
      * @param record
      */
    public void addJob(QuartzVo vo){
        String className = vo.getClassName();
        String name = vo.getJobName();
        String group = vo.getJobGroup();
        String cronExpression = vo.getCronExpression();
        this.addJob(name, group, className, cronExpression);
    }
    public void addJob(String name, String group, String className, String cronExpression) {
        Class<? extends Job> jobClazz = null;
        try {
            jobClazz = Class.forName(className).asSubclass(Job.class);
        } catch (Exception e) {
            log.error(className+"没有继承job,e=="+e);
        }
        JobDataMap map = new JobDataMap();
        addJob(name,group,jobClazz,cronExpression,map);
    }
    public void addJob(String name, String group, Class<? extends Job> jobClazz, String cronExpression,JobDataMap map) {
        try {
            // 构造任务
            JobDetail job = newJob(jobClazz).withIdentity(name, group).usingJobData(map).build();
            // 构造任务触发器
            Trigger trg = newTrigger().withIdentity(name, group).withSchedule(cronSchedule(cronExpression)).build();
            // 将作业添加到调度器
            scheduler.scheduleJob(job, trg);
            log.info("创建作业=> [作业名称:" + name + " 作业组:" + group + "] ");
        } catch (SchedulerException e) {
            e.printStackTrace();
            log.error("创建作业=> [作业名称:" + name + " 作业组:" + group + "]=> [失败]");
        }
    }

    /**
     * 移除定时任务
     * @param name
     * @param group
     * @throws SchedulerException
     */
    public void removeJob(String name, String group) throws SchedulerException {
            TriggerKey tk = TriggerKey.triggerKey(name, group);
            scheduler.pauseTrigger(tk);// 停止触发器
            scheduler.unscheduleJob(tk);// 移除触发器
            JobKey jobKey = JobKey.jobKey(name, group);
            scheduler.deleteJob(jobKey);// 删除作业
            log.info("删除作业=> [作业名称:" + name + " 作业组:" + group + "] ");
    }

    /**
     * 启动定时任务
     */
    public void start() {
        try {
            scheduler.start();
            log.info("启动调度器 ");
        } catch (SchedulerException e) {
            e.printStackTrace();
            log.error("启动调度器=> [失败]");
        }
    }

    /**
     * 关闭定时任务
     */
    public void shutdown() {
        try {
            scheduler.shutdown();
            log.info("停止调度器 ");
        } catch (SchedulerException e) {
            e.printStackTrace();
            log.error("停止调度器=> [失败]");
        }
    }
}

定时任务管理器用到的自定义QuartzVo:

package com.smartteam.vo.quartz;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;

/**
 * @description:
 * @program: midplatform-privilege
 * @author: XiaoDeng
 * @created: 2019-08-06
 **/
@Data
@ApiModel
public class QuartzVo implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "时间到了要执行的类名:com.information.quartz.YygQuartzJob")
    private String className;

    @ApiModelProperty(value = "自定义任务名:定时任务提醒")
    private String jobName;

    @ApiModelProperty(value = "自定义组名:System")
    private String jobGroup;

    @ApiModelProperty(value = "cron定时表达式:00 16 18 18 06 ?")
    private String cronExpression;

}

时间到了,跳转的的YygQuartzJob类:

package com.smartteam.quartz;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import com.smartteam.common.quartz.QuartzServletContextListener;
import com.smartteam.service.SampleTryEntryService;
import com.smartteam.service.impl.SampleTryEntryServiceImpl;

/**
 * 动态定时器
 * @author Administrator
 *
 */
@Component
public class YygQuartzJob implements Job {

    @Override
    public void execute(JobExecutionContext jobContext) throws JobExecutionException {
        // 定时任务quartz的job中注入service为null解决方案
        ServletContext context = null;
        try {
            context = (ServletContext) jobContext.getScheduler().getContext()
                    .get(QuartzServletContextListener.MY_CONTEXT_NAME);
        } catch (SchedulerException e1) {
            e1.printStackTrace();
        }
        WebApplicationContext cxt = (WebApplicationContext) context.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
        SampleTryEntryService sampleTryEntryService = (SampleTryEntryService) cxt.getBean("sampleTryEntryServiceImpl");
        // 定时任务要用到的信息
        List<Map<String, Object>> maps = SampleTryEntryServiceImpl.scymaps;
        ................逻辑处理................
        // 这里重新调用定时任务的方法,业务需求
        ampleTryEntryService.scrhySendMessage();
    }

}

QuartzServletContextListener类:定时任务quartz的job中注入service为null解决方案

package com.smartteam.common.quartz;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;

import org.quartz.SchedulerException;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.stereotype.Component;

/**
 * 定时任务quartz的job中注入service为null解决类QuartzServletContextListener
 * @author Administrator
 *
 */
@Component
public class QuartzServletContextListener extends QuartzInitializerListener {

    public static final String MY_CONTEXT_NAME = "servletContext";

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // TODO Auto-generated method stub
        super.contextDestroyed(sce);
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // TODO Auto-generated method stub
        super.contextInitialized(sce);
        ServletContext servletContext = sce.getServletContext();
        StdSchedulerFactory factory = (StdSchedulerFactory) servletContext
                .getAttribute(QuartzInitializerListener.QUARTZ_FACTORY_KEY);
        try {
            factory.getScheduler().getContext()
                    .put(QuartzServletContextListener.MY_CONTEXT_NAME, servletContext);
        } catch (SchedulerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

maven依赖:

<!-- quartz定时任务 -->
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.0</version>
</dependency>

原文地址:https://www.cnblogs.com/noire/p/11368264.html

时间: 2024-10-15 05:35:23

SSM的quartz动态定时器的相关文章

quartz+spring 实现多任务动态定时器问题

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"   

Spring+quartz 动态任务调度

需求是这样的:系统中会有很多的执行时间,三个或者四个这样,不确定,以后可能是五个!当用户在页面添加执行时间时,我们后台也要对应执行用户添加的时间. 数据库设计: DROP TABLE IF EXISTS `test_time_task`; CREATE TABLE `test_time_task` ( `status` int(11) DEFAULT NULL COMMENT '状态:0为正常,1为禁用', `job` varchar(255) CHARACTER SET utf8 DEFAUL

使用quartz实现定时器功能

首先导入两个包 1 <dependency> 2 <groupId>org.quartz-scheduler</groupId> 3 <artifactId>quartz</artifactId> 4 <version>2.2.2</version> 5 </dependency> 6 <dependency> 7 <groupId>org.quartz-scheduler</gr

Spring4整合quartz2.2.3,quartz动态任务

Spring4整合quartz2.2.3,quartz动态任务 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ?Copyright 蕃薯耀 2017年9月6日 http://www.cnblogs.com/fanshuyao/ 可以直接看总结篇: http://www.cnblogs.com/fa

Quartz动态添加、修改和删除定时任务

任务调度开源框架Quartz动态添加.修改和删除定时任务 Quartz 是个开源的作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制.Quartz框架包含了调度器监听.作业和触发器监听.你可以配置作业和触发器监听为全局监听或者是特定于作业和触发器的监听.Quartz 允许开发人员根据时间间隔(或天)来调度作业.它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联.整合了 Quartz 的应用程序可以重用来自不同事件的作业,还可以为一个事件组合多个作业.并且还

Spring整合Quartz实现动态定时器

一 : 首先了解spring定时器所使用到的场景 比如 : 定时统计报表,或者登录账户密码验证失败冻结账户后,每晚12点将账户解锁等等... 使用jar包 : 2.0使用方法不同 <!-- 定时器 --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>1.8.6</versio

netty实现动态定时器

最近开发一个后台游戏服务器,需要定时给 客户端推送 作物状态: 1.需要开启一个线程,执行定时任务 2.需要动态添加定时任务 3.需要动态修改定时任务时间. 网上找到两种方式:quartz服务 和HashedWheelTimer 这两种方式 ,项目中用的是HashedWheelTimer ,相关API可以自行百度或者看源码. 创建HashedWheelTimer  对象 通过 map<String,TimerOut> 来存储 定时器 通过设置定时任务返回timeOut  对象,存放在map中,

任务调度开源框架Quartz动态添加、修改和删除定时任务

Quartz 是个开源的作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制.Quartz框架包含了调度器监听.作业和触发器监听.你可以配置作业和触发器监听为全局监听或者是特定于作业和触发器的监听.Quartz 允许开发人员根据时间间隔(或天)来调度作业.它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联.整合了 Quartz 的应用程序可以重用来自不同事件的作业,还可以为一个事件组合多个作业.并且还能和Spring配置整合使用.Quartz在功能上远远超越

一个Spring Scheduler (Quartz) 动态添加,删除,修改任务的例子

要求 根据任务清单执行不定数量,不定频率的定时任务.并且需要动态添加,删除,修改任务. 代码 public class JobExample {      public static void main(String[] args) throws Exception {         // Job的配置信息,可以从数据库或配置文件中获取         List<JobParameter> list = new ArrayList<JobParameter>();