码迷,mamicode.com
首页 > 其他好文 > 详细

SSM的quartz动态定时器

时间:2019-08-17 15:03:40      阅读:70      评论:0      收藏:0      [点我收藏+]

标签:out   enc   回收   service   return   tee   sub   Servle   express   

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>

 

SSM的quartz动态定时器

标签:out   enc   回收   service   return   tee   sub   Servle   express   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!