定时任务-动态定时任务(springboot+org.quartz)

添加依赖

<!-- Quartz定时任务 -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-quartz</artifactId>
	</dependency>

添加配置

  #quartz定时任务,采用数据库方式
 spring:
  quartz:
    job-store-type: jdbc    #数据持久化方式,可选值:MEMORY、JDBC
    initialize-schema: embedded
    #设置自动启动,默认为 true
    auto-startup: false
    #启动时更新己存在的Job
    overwrite-existing-jobs: true
    properties:
      org:
        quartz:
          scheduler:
            instanceName: MyScheduler
            instanceId: AUTO
          jobStore:
          	#如果不需要将调度命令(例如添加和删除triggers)绑定到其他事务,那么可以通过使用 JobStoreTX 管理事务
            class: org.quartz.impl.jdbcjobstore.JobStoreTX
            #设置数据库驱动代理,StdJDBCDelegate 是一个使用 JDBC 代码来执行其工作的代理. 其他代			  理可以在"org.quartz.impl.jdbcjobstore“包或其子包中找到
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
            #通知 JobStore 使用的表前缀
            tablePrefix: QRTZ_
            #是否加入集群
            isClustered: true
            misfireThreshold: 60000
            ##容许的最大作业延长时间
            clusterCheckinInterval: 10000
          threadPool:
          	#quartz 使用的线程池类型,org.quartz.spi.ThreadPool
            class: org.quartz.simpl.SimpleThreadPool
            #线程池中的线程总个数,表示最多可以同时执行的个任务/作业个数
            threadCount: 10
            #线程优先级
            threadPriority: 5
            #线程继承初始化线程的上下文类加载器
            threadsInheritContextClassLoaderOfInitializingThread: true

表结构

在这里插入图片描述

具体代码

    ------------------------controller开始----------------------------
    

 1. 添加
 /**
	 * 添加定时任务
	 *
	 * @param quartzJob
	 * @return
	 */
	@RequestMapping(value = "/add", method = RequestMethod.POST)
	public Result<?> add(@RequestBody QuartzJob quartzJob) {
		String jobClassName = quartzJob.getJobClassName();
		if(isContainChinese(jobClassName)){
			return Result.error("JobClassName参数有误!");
		}
		quartzJobService.saveAndScheduleJob(quartzJob);
		return Result.ok("创建定时任务成功");
	}
 2. 修改
  /**
	 * 更新定时任务
	 *
	 * @param quartzJob
	 * @return
	 */
	@RequestMapping(value = "/edit", method = RequestMethod.PUT)
	public Result<?> eidt(@RequestBody QuartzJob quartzJob) {
		try {
			String jobClassName = quartzJob.getJobClassName();
			if(isContainChinese(jobClassName)){
				return Result.error("JobClassName参数有误!");
			}
			quartzJobService.editAndScheduleJob(quartzJob);
		} catch (SchedulerException e) {
			log.error(e.getMessage(),e);
			return Result.error("更新定时任务失败!");
		}
	    return Result.ok("更新定时任务成功!");
	}
 3. 删除
 	/**
	 * 通过id删除
	 *
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
	public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
		QuartzJob quartzJob = quartzJobService.getById(id);
		if (quartzJob == null) {
			return Result.error("未找到对应实体");
		}
		quartzJobService.deleteAndStopJob(quartzJob);
        return Result.ok("删除成功!");

 4. 暂停任务
 /**
	 * 暂停定时任务
	 *
	 * @param id
	 * @return
	 */
	@GetMapping(value = "/pause")
	@ApiOperation(value = "暂停定时任务")
	public Result<Object> pauseJob(@RequestParam(name = "id") String id) {
		QuartzJob job = quartzJobService.getById(id);
		if (job == null) {
			return Result.error("定时任务不存在!");
		}
		quartzJobService.pause(job);
		return Result.ok("暂停定时任务成功");
	}
 5. 恢复任务
 /**
	 * 启动定时任务
	 *
	 * @param id
	 * @return
	 */
	@GetMapping(value = "/resume")
	@ApiOperation(value = "恢复定时任务")
	public Result<Object> resumeJob(@RequestParam(name = "id") String id) {
		QuartzJob job = quartzJobService.getById(id);
		if (job == null) {
			return Result.error("定时任务不存在!");
		}
		quartzJobService.resumeJob(job);
		//scheduler.resumeJob(JobKey.jobKey(job.getJobClassName().trim()));
		return Result.ok("恢复定时任务成功");
	}
 6. 立即执行
 /**
	 * 立即执行
	 * @param id
	 * @return
	 */
	@GetMapping("/execute")
	public Result<?> execute(@RequestParam(name = "id", required = true) String id) {
		QuartzJob quartzJob = quartzJobService.getById(id);
		if (quartzJob == null) {
			return Result.error("未找到对应实体");
		}
		try {
			quartzJobService.execute(quartzJob);
		} catch (Exception e) {
			//e.printStackTrace();
			log.info("定时任务 立即执行失败>>"+e.getMessage());
			return Result.error("执行失败!");
		}
		return Result.ok("执行成功!");
	}
  ---------------------controller结束---------------------------------
    
 -------------------------service开始----------------------------------------

 7. 保存

	/**
	 * 保存&启动定时任务
	 */
	@Override
	public boolean saveAndScheduleJob(QuartzJob quartzJob) {
		// DB设置修改
		quartzJob.setDelFlag(CommonConstant.DEL_FLAG_0);
		boolean success = this.save(quartzJob);
		if (success) {
			if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
				// 定时器添加
				this.schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
			}
		}
		return success;
	}

 /**
	 * 添加定时任务
	 *
	 * @param jobClassName
	 * @param cronExpression
	 * @param parameter
	 */
	private void schedulerAdd(String id, String jobClassName, String cronExpression, String parameter) {
		try {
			// 启动调度器
			scheduler.start();

			// 构建job信息
			JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(id).usingJobData("parameter", parameter).build();

			// 表达式调度构建器(即任务执行的时间)
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);

			// 按新的cronExpression表达式构建一个新的trigger
			CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(id).withSchedule(scheduleBuilder).build();

			scheduler.scheduleJob(jobDetail, trigger);
		} catch (SchedulerException e) {
			throw new JeecgBootException("创建定时任务失败", e);
		} catch (RuntimeException e) {
			throw new JeecgBootException(e.getMessage(), e);
		}catch (Exception e) {
			throw new JeecgBootException("后台找不到该类名:" + jobClassName, e);
		}
	}

 8. 编辑
    /**
	 * 编辑&启停定时任务
	 * @throws SchedulerException
	 */
	@Override
	public boolean editAndScheduleJob(QuartzJob quartzJob) throws SchedulerException {
		if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
			schedulerDelete(quartzJob.getId());
			schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
		}else{
			//暂停任务
			scheduler.pauseJob(JobKey.jobKey(quartzJob.getId()));
		}
		return this.updateById(quartzJob);
	}

 9. 删除定时任务
    /**
	 * 删除定时任务
	 *
	 * @param id
	 */
	private void schedulerDelete(String id) {
		try {
			scheduler.pauseTrigger(TriggerKey.triggerKey(id));// 停止触发器
			scheduler.unscheduleJob(TriggerKey.triggerKey(id));// 移除触发器
			scheduler.deleteJob(JobKey.jobKey(id));// 删除任务
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new JeecgBootException("删除定时任务失败");
		}
	} 

 10. 暂停定时任务
     /**
	 * 暂停定时任务
	 * @param quartzJob
	 */
	@Override
	public void pause(QuartzJob quartzJob){
		schedulerDelete(quartzJob.getId());
		quartzJob.setStatus(CommonConstant.STATUS_DISABLE);
		this.updateById(quartzJob);
	}

 11. 恢复定时任务
    /**
	 * 恢复定时任务
	 */
	@Override
	public boolean resumeJob(QuartzJob quartzJob) {
		schedulerDelete(quartzJob.getId());
		schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
		quartzJob.setStatus(CommonConstant.STATUS_NORMAL);
		return this.updateById(quartzJob);
	}

 12. 立即执行
     /**
	 * 执行定时任务
	 * @param quartzJob
	 * @throws Exception
	 */
	@Override
	public void execute(QuartzJob quartzJob) throws Exception {
		String jobName = quartzJob.getJobClassName().trim();
		Date startDate = new Date();
		String ymd = DateUtils.date2Str(startDate,DateUtils.yyyymmddhhmmss.get());
		String identity =  jobName + ymd;
		//0.1秒后执行 只执行一次
		startDate.setTime(startDate.getTime() + 100L);
		// 定义一个Trigger
		SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger()
				.withIdentity(identity, JOB_TEST_GROUP)
				.startAt(startDate)
				.build();
		// 构建job信息
		JobDetail jobDetail = JobBuilder.newJob(getClass(jobName).getClass()).withIdentity(identity).usingJobData("parameter", quartzJob.getParameter()).build();
		// 将trigger和 jobDetail 加入这个调度
		scheduler.scheduleJob(jobDetail, trigger);
		// 启动scheduler
		scheduler.start();
	}

 -----------------------------service结束------------------------------------

执行的任务内容

/**
 * 定时任务内容
 *
 */
@Slf4j
public class BridgeDeviceJob implements Job {
	/**
	 * 当前任务内容
	 * @param jobExecutionContext
	 * @throws JobExecutionException
	 */
	@Override
	public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
		log.info(String.format(" 数据接收定时任务 !  时间:" + DateUtils.getTimestamp()));
		//具体任务内容
	}
}
注意:1.实现org.quartz.Job接口,重新execute()方法.方法中写任务具体内容.

补充点

CronTrigger

withMisfireHandlingInstructionDoNothing
——不触发立即执行
——等待下次Cron触发频率到达时刻开始按照Cron频率依次执行

withMisfireHandlingInstructionIgnoreMisfires
——以错过的第一个频率时间立刻开始执行
——重做错过的所有频率周期后
——当下一次触发频率发生时间大于当前时间后,再按照正常的Cron频率依次执行

withMisfireHandlingInstructionFireAndProceed
——以当前时间为触发频率立刻触发一次执行
——然后按照Cron频率依次执行
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值