Spring mvc + Mybatis + quartz + swagger 定时任务管理[新增、编辑、删除、修改]

3 篇文章 0 订阅
2 篇文章 0 订阅

    最近公司在分发系统整合,原本选型阶段选择xxl-job国内开源框架,了解后,在这个框架,实际用不到其中的十分之一。利用闲暇时间,自己写了一个定时任务Demo

相关接口描述


Controller

/**
 * 定时任务
 * @author xiaozhi 2018年4月27日 上午11:30:29
 */
@RestController
@RequestMapping("quartz")
@Api(value="/quartz", description="定时任务接口", produces="application/json")
public class JobController {

	@Autowired
	private JobService jobService;
	
	@RequestMapping(method = RequestMethod.POST, value = "/add")
	@ApiOperation(value = "新增任务", httpMethod = "POST", response = ReturnMsg.class, notes = "新增任务", position = 2)
	public ReturnMsg add(@RequestBody Job job) {
		return jobService.addJob(job);
	}
	
	@RequestMapping(method = RequestMethod.POST, value = "/edit")
	@ApiOperation(value = "编辑任务", httpMethod = "POST", response = ReturnMsg.class, notes = "编辑任务", position = 3)
	public ReturnMsg edit(@RequestBody Job job){
		return jobService.editJob(job);
	}
	
	@RequestMapping(method = RequestMethod.POST, value = "/del")
	@ApiOperation(value = "删除任务", httpMethod = "POST", response = ReturnMsg.class, notes = "删除任务", position = 4)
	public ReturnMsg del(@RequestParam("jobId") Long jobId){
		return jobService.delJob(jobId);
	}
	
	@RequestMapping(method = RequestMethod.POST, value = "/list")
	@ApiOperation(value = "任务列表", httpMethod = "POST", response = ReturnMsg.class, notes = "任务列表", position = 1)
	public ReturnMsg list(){
		return jobService.list();
	}

}

Service

/**
 * 定时任务ServiceImpl
 * 
 * @author xiaozhi 2018年4月27日 下午1:46:35
 */
@Service("jobServiceImpl")
public class JobServiceImpl extends AbstractService implements JobService {

	@Autowired
	private Scheduler scheduler;

	@PostConstruct
	public void initJob() {
		try {
			List<Job> jobList = this.baseDAO.selectListByMappingId("selectJobAll");
			for (Job job : jobList) {
				CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, job.getJobId());
				// 如果不存在,则创建
				if (cronTrigger == null) {
					ScheduleUtils.createScheduleJob(scheduler, job);
				} else {
					ScheduleUtils.updateScheduleJob(scheduler, job);
				}
			}
		} catch (Exception e) {
			logger.info("系统启动初始化,加载所有定时任务 Error Msg = " + e.getMessage(), e);
		}
	}

	/**
	 * 添加/更新定时任务 @author xiaozhi 2018年4月27日 下午6:33:32 @param job 定时任务参数集 @return
	 * ReturnMsg @throws
	 */
	@Override
	public ReturnMsg addJob(Job job) {
		try {
			Long jobId = job.getJobId();
			// 若任务ID存在,则更新操作,反之,新增操作
			if (jobId != null) {
				int check = this.baseDAO.update(job, "updateJobCron");
				if (check > 0) {
					ScheduleUtils.updateScheduleJob(scheduler, job);
					return new ReturnMsg(ReturnMsg.SUCCESS, "任务已存在, 更新成功");
				}
			} else {
				job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
				int check = this.baseDAO.insert(job, "insertJob");
				if (check > 0) {
					ScheduleUtils.createScheduleJob(scheduler, job);
					return new ReturnMsg(ReturnMsg.SUCCESS, "新增成功");
				}
			}
		} catch (Exception e) {
			logger.info("添加/更新定时任务 Error Msg = " + e.getMessage(), e);
		}
		return new ReturnMsg(ReturnMsg.FAIL, "操作成功");
	}

	/**
	 * 删除定时任务 @author xiaozhi 2018年4月27日 下午6:35:05 @param jobId 任务ID @return
	 * ReturnMsg @throws
	 */
	@Override
	public ReturnMsg delJob(Long jobId) {
		try {
			// 查询是否存在
			Job job = this.baseDAO.selectOne(jobId, "selectJobById");
			if (job != null && job.getJobId() > 0) {
				int check = this.baseDAO.delete(jobId, "deleteJobById");
				if (check > 0) {
					ScheduleUtils.deleteScheduleJob(scheduler, jobId);
					return new ReturnMsg(ReturnMsg.SUCCESS, "删除成功");
				}
			}
		} catch (Exception e) {
			logger.info("删除定时任务 Error Msg = " + e.getMessage(), e);
		}
		return new ReturnMsg(ReturnMsg.FAIL, "删除失败");
	}

	/**
	 * 编辑定时任务 @author xiaozhi 2018年4月27日 下午6:35:57 @param job 定时任务参数集 @return
	 * ReturnMsg @throws
	 */
	@Override
	public ReturnMsg editJob(Job job) {
		try {
			if (job != null && job.getStatus() == 0) {
				job.setStatus(ScheduleConstants.Status.NORMAL.getValue());
				int check = this.baseDAO.update(job, "updateJob");
				if (check > 0) {
					ScheduleUtils.resumeJob(scheduler, job.getJobId());
				}
				return new ReturnMsg(ReturnMsg.SUCCESS, "编辑成功!");
			} else if (job != null && job.getStatus() == 1) {
				job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
				int check = this.baseDAO.update(job, "updateJob");
				if (check > 0) {
					ScheduleUtils.pauseJob(scheduler, job.getJobId());
				}
				return new ReturnMsg(ReturnMsg.SUCCESS, "编辑成功!");
			}
		} catch (Exception e) {
			logger.info("编辑定时任务 Error Msg = " + e.getMessage(), e);
		}
		return new ReturnMsg(ReturnMsg.FAIL, "编辑失败!");
	}

	/**
	 * 查询定时任务列表 @author xiaozhi 2018年4月27日 下午7:12:00 @return ReturnMsg @throws
	 */
	@Override
	public ReturnMsg list() {
		try {
			List<Job> jobList = this.baseDAO.selectListByMappingId("selectJobList");
			TableDataInfo pageData = PageUtils.pageDB(jobList);
			return new ReturnMsg(ReturnMsg.SUCCESS, "查询成功", pageData);
		} catch (Exception e) {
			logger.info("查询定时任务列表 Error Msg = " + e.getMessage(), e);
		}
		return new ReturnMsg(ReturnMsg.FAIL, "查询失败");
	}

}

定时任务工具类

/**
 * 定时任务工具类
 * 
 * @author xiaozhi 2018年4月28日 上午9:18:56
 */
public class ScheduleUtils {

	// 初始化log
	private static final Logger log = LoggerFactory.getLogger(ScheduleUtils.class);

	private final static String JOB_NAME = "TASK_";

	/**
	 * 获取触发器key
	 */
	public static TriggerKey getTriggerKey(Long jobId) {
		return TriggerKey.triggerKey(JOB_NAME + jobId);
	}

	/**
	 * 获取jobKey
	 */
	public static JobKey getJobKey(Long jobId) {
		return JobKey.jobKey(JOB_NAME + jobId);
	}

	/**
	 * 获取表达式触发器
	 */
	public static CronTrigger getCronTrigger(Scheduler scheduler, Long jobId) {
		try {
			return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId));
		} catch (SchedulerException e) {
			log.error(e.getMessage());
		}
		return null;
	}

	/**
	 * 创建定时任务
	 */
	public static void createScheduleJob(Scheduler scheduler, Job job) {
		try {
			// 构建job信息
			JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(job.getJobId())).build();
			// 表达式调度构建器
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
			// 按新的cronExpression表达式构建一个新的trigger
			CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(job.getJobId()))
					.withSchedule(scheduleBuilder).build();
			// 放入参数,运行时的方法可以获取
			jobDetail.getJobDataMap().put(ScheduleConstants.JOB_PARAM_KEY, job);
			scheduler.scheduleJob(jobDetail, trigger);
			// 暂停任务
			if (job.getStatus() == ScheduleConstants.Status.PAUSE.getValue()) {
				pauseJob(scheduler, job.getJobId());
			}
		} catch (SchedulerException e) {
			log.error(e.getMessage());
		}
	}

	/**
	 * 更新定时任务
	 */
	public static void updateScheduleJob(Scheduler scheduler, Job job) {
		try {
			TriggerKey triggerKey = getTriggerKey(job.getJobId());
			// 表达式调度构建器
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
			CronTrigger trigger = getCronTrigger(scheduler, job.getJobId());
			// 按新的cronExpression表达式重新构建trigger
			trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
			// 参数
			trigger.getJobDataMap().put(ScheduleConstants.JOB_PARAM_KEY, job);
			scheduler.rescheduleJob(triggerKey, trigger);
			// 暂停任务
			if (job.getStatus() == ScheduleConstants.Status.PAUSE.getValue()) {
				pauseJob(scheduler, job.getJobId());
			}
		} catch (SchedulerException e) {
			log.error(e.getMessage());
		}
	}

	/**
	 * 立即执行任务
	 */
	public static void run(Scheduler scheduler, Job job) {
		try {
			// 参数
			JobDataMap dataMap = new JobDataMap();
			dataMap.put(ScheduleConstants.JOB_PARAM_KEY, job);
			scheduler.triggerJob(getJobKey(job.getJobId()), dataMap);
		} catch (SchedulerException e) {
			log.error(e.getMessage());
		}
	}

	/**
	 * 暂停任务
	 */
	public static void pauseJob(Scheduler scheduler, Long jobId) {
		try {
			scheduler.pauseJob(getJobKey(jobId));
		} catch (SchedulerException e) {
			log.error(e.getMessage());
		}
	}

	/**
	 * 恢复任务
	 */
	public static void resumeJob(Scheduler scheduler, Long jobId) {
		try {
			scheduler.resumeJob(getJobKey(jobId));
		} catch (SchedulerException e) {
			log.error(e.getMessage());
		}
	}

	/**
	 * 删除定时任务
	 */
	public static void deleteScheduleJob(Scheduler scheduler, Long jobId) {
		try {
			scheduler.deleteJob(getJobKey(jobId));
		} catch (SchedulerException e) {
			log.error(e.getMessage());
		}
	}
}

    系统启动的时候,首先查询数据库中所有定时任务,加载至 scheduler 中。

    持久层,我使用BaseDao工具类操作

定时任务执行,采用 重载QuartzJobBean-executeInternal,在执行定时任务同时也会把运行日志写入至数据库中。

public class ScheduleJob extends QuartzJobBean {
	
	private static final Logger log = LoggerFactory.getLogger(ScheduleJob.class);

	private ExecutorService service = Executors.newSingleThreadExecutor();

	/**
	 * 重载QuartzJobBean-executeInternal
	 */
	@Override
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
		Job job = (Job) context.getMergedJobDataMap().get(ScheduleConstants.JOB_PARAM_KEY);
		JobLogService jobLogService = (JobLogService) SpringUtils.getBean(JobLogService.class);
		// 定时任务日志数据入库
		JobLog jobLog = new JobLog();
		jobLog.setJobName(job.getJobName());
		jobLog.setJobGroup(job.getJobGroup());
		jobLog.setMethodName(job.getMethodName());
		jobLog.setParams(job.getParams());
		jobLog.setCreateTime(new Date());
		long startTime = System.currentTimeMillis();
		try {
			// 执行任务
			log.info("任务开始执行 - 名称:{} 方法:{}", job.getJobName(), job.getMethodName());
			ScheduleRunnable task = new ScheduleRunnable(job.getJobName(), job.getMethodName(), job.getParams());
			Future<?> future = service.submit(task);
			future.get();
			long times = System.currentTimeMillis() - startTime;
			// 任务状态 0:成功 1:失败
			jobLog.setIsException(0);
			jobLog.setJobMessage(job.getJobName() + " 总共耗时:" + times + "毫秒");
			log.info("任务执行结束 - 名称:{} 耗时:{} 毫秒", job.getJobName(), times);
		} catch (Exception e) {
			log.info("任务执行失败 - 名称:{} 方法:{}", job.getJobName(), job.getMethodName());
			log.error("任务执行异常  - :", e);
			log.info("Error Msg = "+e.getMessage(), e);
			long times = System.currentTimeMillis() - startTime;
			jobLog.setJobMessage(job.getJobName() + " 总共耗时:" + times + "毫秒");
			// 任务状态 0:成功 1:失败
			jobLog.setIsException(1);
			jobLog.setExceptionInfo(e.toString());
		} finally {
			// 添加定时任务运行日志
			jobLogService.addJobLog(jobLog);
		}
	}
}
下载地址: https://download.csdn.net/download/everyday_hzg/10387684

欢迎吐槽,共同进步。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄咾邪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值