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>

猜你喜欢

转载自www.cnblogs.com/noire/p/11368264.html