Quartz实战:基于Quartz实现定时任务的动态调度,实现定时任务的增删改查

这篇具有很好参考价值的文章主要介绍了Quartz实战:基于Quartz实现定时任务的动态调度,实现定时任务的增删改查。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、Quartz基础

Quartz使用文档,使用Quartz实现动态任务,Spring集成Quartz,Quartz集群部署,Quartz源码分析

二、使用Quartz实现定时任务的动态调度

1、使用Quartz-jobStore 持久化

Quartz使用文档,使用Quartz实现动态任务,Spring集成Quartz,Quartz集群部署,Quartz源码分析

2、前端页面实现效果图

Quartz实战:基于Quartz实现定时任务的动态调度,实现定时任务的增删改查,java第三方框架,Quartz

3、自定义job表

CREATE database quartz;

CREATE TABLE `sys_job` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `job_name` varchar(512) NOT NULL COMMENT '任务名称',
  `job_group` varchar(512) NOT NULL COMMENT '任务组名',
  `job_cron` varchar(512) NOT NULL COMMENT '时间表达式',
  `job_class_path` varchar(1024) NOT NULL COMMENT '类路径,全类型',
  `job_data_map` varchar(1024) DEFAULT NULL COMMENT '传递map参数',
  `job_status` int(2) NOT NULL COMMENT '状态:1启用 0停用',
  `job_describe` varchar(1024) DEFAULT NULL COMMENT '任务功能描述',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8;

-- 插入3条数据,3个任务
-- 注意第三条,是一个发送邮件的任务,需要改成你自己的QQ和授权码。不知道什么是授权码的自己百度。
INSERT INTO `sys_job` (`id`, `job_name`, `job_group`, `job_cron`, `job_class_path`, `job_data_map`, `job_status`, `job_describe`) VALUES (22, 'test', 'test', '*/20 * * * * ?', 'com.demo.task.TestTask1', NULL, 1, 'a job a');
INSERT INTO `sys_job` (`id`, `job_name`, `job_group`, `job_cron`, `job_class_path`, `job_data_map`, `job_status`, `job_describe`) VALUES (23, 'test2', 'test', '*/30 * * * * ?', 'com.demo.task.TestTask2', NULL, 1, 'another job');
INSERT INTO `sys_job` (`id`, `job_name`, `job_group`, `job_cron`, `job_class_path`, `job_data_map`, `job_status`, `job_describe`) VALUES (24, 'test3', 'mail', '*/10 * * * * ?', 'com.demo.task.TestTask3', '{\"data\":{\"loginAccount\":\"改成你的QQ邮箱\",\"loginAuthCode\":\"改成你的邮箱授权码\",\"sender\":\"改成你的QQ邮箱\",\"emailContent\":\"    你好。\",\"emailContentType\":\"text/html;charset=utf-8\",\"emailSubject\":\"十万火急\",\"recipients\":\"改成你要的收件人邮箱,可以有多个,英文逗号隔开\"}}', 1, 'fdsafdfds');

-- 清空表的脚本
DELETE FROM QRTZ_BLOB_TRIGGERS;
DELETE FROM QRTZ_CALENDARS;
DELETE FROM QRTZ_CRON_TRIGGERS;
DELETE FROM QRTZ_FIRED_TRIGGERS;
DELETE FROM QRTZ_LOCKS;
DELETE FROM QRTZ_PAUSED_TRIGGER_GRPS;
DELETE FROM QRTZ_SCHEDULER_STATE;
DELETE FROM QRTZ_SIMPLE_TRIGGERS;
DELETE FROM QRTZ_SIMPROP_TRIGGERS;
DELETE FROM QRTZ_TRIGGERS;
DELETE FROM QRTZ_JOB_DETAILS;
COMMIT;

4、增删改查Controller

@Controller()
@RequestMapping("/job")
public class JobController {
	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private ISysJobService sysJobService;

	/**
	 * 打开列表页
	 * @return
	 */
	@RequestMapping("/jobList")
	public String jobList() {
		return "jobListPage";
	}

	/**
	 * 打开详情界面
	 * @param id
	 * @param model
	 * @return
	 */
	@RequestMapping("/toDetail")
	public String toDetail(Integer id, Model model) {
		SysJob job = sysJobService.selectByPrimaryKey(id);
		model.addAttribute("job",job);
		return "jobDetail";
	}

	/**
	 * 打开修改界面
	 * @param id
	 * @param model
	 * @return
	 */
	@RequestMapping("/toUpdate")
	public String toUpdate(Integer id, Model model) {
		SysJob job = sysJobService.selectByPrimaryKey(id);
		model.addAttribute("job",job);
		return "jobUpdate";
	}

	/**
	 * 打开新增界面
	 * @return
	 */
	@RequestMapping("/toJob")
	public String toJob (){
		return "jobAdd";
	}

	/**
	 * 查询任务列表(带分页)
	 * 
	 * @return
	 */
	@RequestMapping(value = "/queryList", method = RequestMethod.GET)
	@ResponseBody
	public LayuiData queryJobList(HttpServletRequest request, HttpServletResponse response) {
		String idStr = request.getParameter("id");
		String jobName = request.getParameter("jobName");
		String jobGroup = request.getParameter("jobGroup");
		String jobCron = request.getParameter("jobCron");
		String jobClassPath = request.getParameter("jobClassPath");
		String jobDescribe = request.getParameter("jobDescribe");

		HashMap<String, String> map = new HashMap<String, String>();
		if (StringUtils.isNotBlank(idStr)) {
			map.put("id", idStr);
		}
		if (StringUtils.isNotBlank(jobName)) {
			map.put("jobName", jobName);
		}
		if (StringUtils.isNotBlank(jobGroup)) {
			map.put("jobGroup", jobGroup);
		}
		if (StringUtils.isNotBlank(jobCron)) {
			map.put("jobCron", jobCron);
		}
		if (StringUtils.isNotBlank(jobClassPath)) {
			map.put("jobClassPath", jobClassPath);
		}
		if (StringUtils.isNotBlank(jobDescribe)) {
			map.put("jobDescribe", jobDescribe);
		}

		int page = Integer.parseInt(request.getParameter("page"));
		int limit = Integer.parseInt(request.getParameter("limit"));
		if(page>=1){
			page = (page-1)*limit;
		}
		LayuiData layuiData = new LayuiData();

		try {
			List<SysJob> jobList = sysJobService.querySysJobList(map);
			int count = sysJobService.getJobCount();
			layuiData.setCode(0);
			layuiData.setCount(count);
			layuiData.setMsg("数据请求成功");
			layuiData.setData(jobList);
			return layuiData;
		} catch (Exception e) {
			throw new BizException("查询任务列表异常:" + e.getMessage());
		}
	}

	/**
	 * 添加定时任务
	 *
	 * @throws Exception
	 */
	@PostMapping(value = "/addJob")
	@ResponseBody
	@Transactional
	public int addjob(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("添加任务开始... ...");
		int num =0;
		String jobName = request.getParameter("jobName");
		String jobClassPath= request.getParameter("jobClassPath");
		String jobGroup= request.getParameter("jobGroup");
		String jobCron= request.getParameter("jobCron");
		String jobDescribe= request.getParameter("jobDescribe");
		String jobDataMap= request.getParameter("jobDataMap");
		
		if (StringUtils.isBlank(jobName)) {
			throw new BizException("任务名称不能为空");
		}
		if (StringUtils.isBlank(jobGroup)) {
			throw new BizException("任务组别不能为空");
		}
		if (StringUtils.isBlank(jobCron)) {
			throw new BizException("Cron表达式不能为空");
		}
		if (StringUtils.isBlank(jobClassPath)) {
			throw new BizException("任务类路径不能为空");
		}
		
		// 参数不为空时校验格式
		if(StringUtils.isNotBlank(jobDataMap)){
			try {
				JSONObject.parseObject(jobDataMap);
			} catch (Exception e) {
				throw new BizException("参数JSON格式错误");
			}
		}
		
		// 已存在校验
		SysJob queryBean = new SysJob();
		queryBean.setJobName(jobName);
		SysJob result = sysJobService.selectByBean(queryBean);
		if (null != result) {
			throw new BizException("任务名为" + jobName + "的任务已存在!");
		}

		SysJob bean = new SysJob();
		bean.setJobName(jobName);
		bean.setJobClassPath(jobClassPath);
		bean.setJobGroup(jobGroup);
		bean.setJobCron(jobCron);
		bean.setJobDescribe(jobDescribe);
		bean.setJobDataMap(jobDataMap);
		bean.setJobStatus(Constant.JOB_STATE.YES);
		try {
			num = sysJobService.insertSelective(bean);
		} catch (Exception e) {
			throw new BizException("新增定时任务失败");
		}
		
		SchedulerUtil.addJob(jobClassPath,jobName, jobGroup, jobCron,jobDataMap);
		return num;
	}
	
	/**
	 * 变更定时任务执行状态
	 * @return
	 * @throws Exception
	 */
	@GetMapping(value = "/changeState")
	@ResponseBody
	public int changeState(@RequestParam(value = "id") String idStr)throws Exception{
        logger.info("变更定时任务状态开始... ...");
		if (StringUtils.isBlank(idStr)) {
			throw new BizException("任务ID不能为空");
		}
		int id = Integer.parseInt(idStr);

		// 校验
		SysJob queryBean = new SysJob();
		queryBean.setId(id);
		SysJob result = sysJobService.selectByBean(queryBean);
		if (null == result) {
			throw new BizException("任务ID为" + id + "的任务不存在!");
		}
		
		SysJob updateBean = new SysJob();
		updateBean.setId(id);
		//如果是现在是启用,则停用
		if(Constant.JOB_STATE.YES == result.getJobStatus()){
			updateBean.setJobStatus(Constant.JOB_STATE.NO);
			//SchedulerUtil.jobPause(result.getJobName(), result.getJobGroup());
		  Boolean b=SchedulerUtil.isResume(result.getJobName(), result.getJobGroup());
		  if (b) {
			  SchedulerUtil.jobdelete(result.getJobName(), result.getJobGroup());
		  }
		}
		
		//如果现在是停用,则启用
		if(Constant.JOB_STATE.NO == result.getJobStatus()){
			updateBean.setJobStatus(Constant.JOB_STATE.YES);
			//SchedulerUtil.jobresume(result.getJobName(), result.getJobGroup());
			 Boolean b=SchedulerUtil.isResume(result.getJobName(), result.getJobGroup());
			 //存在则激活,不存在则添加
			  if (b) {
				  SchedulerUtil.jobresume(result.getJobName(), result.getJobGroup());
			  }else {
				  SchedulerUtil.addJob(result.getJobClassPath(),result.getJobName(), result.getJobGroup(), result.getJobCron(),result.getJobDataMap());
			}
		}
		
		try {
			sysJobService.updateByPrimaryKeySelective(updateBean);
		} catch (Exception e) {
			throw new BizException("更新数据库的定时任务信息异常!");
		}
		// 1表示成功
		return 1;
		
	}

	/**
	 * 删除一个任务
	 *
	 * @throws Exception
	 */
	@PostMapping(value = "/deleteJob")
	@ResponseBody
	public int deletejob(@RequestParam(value = "id") String idStr) throws Exception {
        logger.info("删除定时任务状态开始... ...");
		int num =0;
		if (StringUtils.isBlank(idStr)) {
			throw new BizException("任务ID不能为空");
		}
		int id = Integer.parseInt(idStr);
		
		// 存在性校验
		SysJob queryBean = new SysJob();
		queryBean.setId(id);
		SysJob result = sysJobService.selectByBean(queryBean);
		if (null == result) {
			throw new BizException("任务ID为" + idStr + "的任务不存在!");
		}
		
		try {
			num = sysJobService.deleteByPrimaryKey(id);
		} catch (Exception e) {
			throw new BizException("从数据库删除定时任务时发生异常!");
		}
		
		SchedulerUtil.jobdelete(result.getJobName(), result.getJobGroup());
		return num;
	}

	/**
	 * 修改定时表达式
	 */
	@RequestMapping("/reSchedulejob")
	@ResponseBody
	public int updateByBean(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("修改定时任务信息开始... ...");
		int num =0;
		String jobCron = request.getParameter("jobCron");
		String jobDescribe = request.getParameter("jobDescribe");
		String idStr = request.getParameter("id");
		int id = Integer.parseInt(idStr);
		// 数据非空校验
		if (!StringUtils.isNotBlank(idStr)) {
			throw new BizException("任务ID不能为空");
		}
		SysJob result = sysJobService.selectByPrimaryKey(id);
		// 数据不存在
		if (null == result) {
			throw new BizException("根据任务ID[" + id + "]未查到相应的任务记录");
		}
		SysJob bean = new SysJob();
		bean.setId(id);
		bean.setJobCron(jobCron);
		bean.setJobDescribe(jobDescribe);
		try {
			num = sysJobService.updateByPrimaryKeySelective(bean);
		} catch (Exception e) {
			throw new BizException("变更任务表达式异常:" + e.getMessage());
		}
		//只有任务状态为启用,才开始运行
		// 如果先启动再手工插入数据,此处会报空指针异常
		if( result.getJobStatus() ==Constant.JOB_STATE.YES ){
			SchedulerUtil.jobReschedule(result.getJobName(), result.getJobGroup(),jobCron);
		}
		
		// 返回成功
		return num;
	}

	/**
	 * 展示任务调度管理页
	 * 
	 * @param request
	 * @param rep
	 * @return
	 */
	@RequestMapping(value = "/jobPage", method = RequestMethod.GET)
	public String getJobPage(HttpServletRequest request, HttpServletResponse rep) {
		return "job/job_info";
	}
}

5、Quartz工具类

/**
 * Quartz工具类
 */
public class SchedulerUtil {
	private static Logger logger = LoggerFactory.getLogger(SchedulerUtil.class);

	/**
	 * 新增定时任务
	 * @param jobClassName 类路径
	 * @param jobName 任务名称
	 * @param jobGroupName 组别
	 * @param cronExpression Cron表达式
	 * @param jobDataMap 需要传递的参数
	 * @throws Exception
	 */
	public static void addJob(String jobClassName,String jobName, String jobGroupName, String cronExpression,String jobDataMap) throws Exception {
		// 通过SchedulerFactory获取一个调度器实例
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler scheduler = sf.getScheduler();
		// 启动调度器
		scheduler.start();
		// 构建job信息
		JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass())
				.withIdentity(jobName, jobGroupName).build();
		// JobDataMap用于传递任务运行时的参数,比如定时发送邮件,可以用json形式存储收件人等等信息
		if (StringUtils.isNotEmpty(jobDataMap)) {
			JSONObject jb = JSONObject.parseObject(jobDataMap);
			Map<String, Object> dataMap =(Map<String, Object>) jb.get("data");
			for (Map.Entry<String, Object> m:dataMap.entrySet()) {
				jobDetail.getJobDataMap().put(m.getKey(),m.getValue());
			}
		}
		// 表达式调度构建器(即任务执行的时间)
		CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
		// 按新的cronExpression表达式构建一个新的trigger
		CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
				.withSchedule(scheduleBuilder).startNow().build();
		try {
			scheduler.scheduleJob(jobDetail, trigger);
		} catch (SchedulerException e) {
			logger.info("创建定时任务失败" + e);
			throw new Exception("创建定时任务失败");
		}
	}
	
	/**
	 * 停用一个定时任务
	 * @param jobName 任务名称
	 * @param jobGroupName 组别
	 * @throws Exception
	 */
	public static void jobPause(String jobName, String jobGroupName) throws Exception {
		// 通过SchedulerFactory获取一个调度器实例
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler scheduler = sf.getScheduler();
		scheduler.pauseJob(JobKey.jobKey(jobName, jobGroupName));
	}
	
	/**
	 * 启用一个定时任务
	 * @param jobName 任务名称
	 * @param jobGroupName 组别
	 * @throws Exception
	 */
	public static void jobresume(String jobName, String jobGroupName) throws Exception {
		// 通过SchedulerFactory获取一个调度器实例
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler scheduler = sf.getScheduler();
		scheduler.resumeJob(JobKey.jobKey(jobName, jobGroupName));
	}
	
	/**
	 * 删除一个定时任务
	 * @param jobName 任务名称
	 * @param jobGroupName 组别
	 * @throws Exception
	 */
	public static void jobdelete(String jobName, String jobGroupName) throws Exception {
		// 通过SchedulerFactory获取一个调度器实例
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler scheduler = sf.getScheduler();
		scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroupName));
		scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroupName));
		scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));
	}
	
	/**
	 * 更新定时任务表达式
	 * @param jobName 任务名称
	 * @param jobGroupName 组别
	 * @param cronExpression Cron表达式
	 * @throws Exception
	 */
	public static void jobReschedule(String jobName, String jobGroupName, String cronExpression) throws Exception {
		try {
			SchedulerFactory schedulerFactory = new StdSchedulerFactory();
			Scheduler scheduler = schedulerFactory.getScheduler();
			TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
			// 表达式调度构建器
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
			CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
			// 按新的cronExpression表达式重新构建trigger
			trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).startNow().build();
			// 按新的trigger重新设置job执行
			scheduler.rescheduleJob(triggerKey, trigger);
		} catch (SchedulerException e) {
			System.out.println("更新定时任务失败" + e);
			throw new Exception("更新定时任务失败");
		}
	}
	
	/**
	 * 检查Job是否存在
	 * @throws Exception
	 */
	public static Boolean isResume(String jobName, String jobGroupName) throws Exception {
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler scheduler = sf.getScheduler();
		TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
		Boolean state = scheduler.checkExists(triggerKey);
	     
		return state;
	}

	/**
	 * 暂停所有任务
	 * @throws Exception
	 */
	public static void pauseAlljob() throws Exception {
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler scheduler = sf.getScheduler();
		scheduler.pauseAll();
	}

	/**
	 * 唤醒所有任务
	 * @throws Exception
	 */
	public static void resumeAlljob() throws Exception {
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler sched = sf.getScheduler();
		sched.resumeAll();
	}

	/**
	 * 获取Job实例
	 * @param classname
	 * @return
	 * @throws Exception
	 */
	public static BaseJob getClass(String classname) throws Exception {
		try {
			Class<?> c = Class.forName(classname);
			return (BaseJob) c.newInstance();
		} catch (Exception e) {
			throw new Exception("类["+classname+"]不存在!");
		}
		
	}

}

6、测试任务类

@DisallowConcurrentExecution
public class TestTask1 implements BaseJob {

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(Thread.currentThread().getName() + " " +sdf.format(date) + " Task1: ----hello1----");
    }
}
public class TestTask2 implements BaseJob {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(Thread.currentThread().getName() + " " +sdf.format(date) + " Task2: ----hello2----");
    }
}
public class TestTask3 implements BaseJob {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ISysJobService sysJobService;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        logger.info("开始执行任务3... ...");
        HashMap<String,String> map = new HashMap<String,String>();
        map.put("jobGroup", "mail");
        map.put("jobStatus", "1");
        List<SysJob> jobList= sysJobService.querySysJobList(map);

        if( null == jobList || jobList.size() ==0){
            logger.info("没有状态为可用的发送邮件任务... ...");
        }

        for (SysJob sysJob:jobList) {
                logger.info("开始发送邮件... ...");
        }
    }
}

7、springboot启动初始化定时任务

/**
 * 这个类用于启动SpringBoot时,加载作业。run方法会自动执行。
 *
 * 另外可以使用 ApplicationRunner
 *
 */
public class InitStartSchedule implements CommandLineRunner {
	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	private ISysJobService sysJobService;
	@Autowired
	private MyJobFactory myJobFactory;
	
	@Override
	public void run(String... args) throws Exception {
		/**
		 * 用于程序启动时加载定时任务,并执行已启动的定时任务(只会执行一次,在程序启动完执行)
		 */
		
		//查询job状态为启用的
		HashMap<String,String> map = new HashMap<String,String>();
		map.put("jobStatus", "1");
		List<SysJob> jobList= sysJobService.querySysJobList(map);
		if( null == jobList || jobList.size() ==0){
			logger.info("系统启动,没有需要执行的任务... ...");
		}
		// 通过SchedulerFactory获取一个调度器实例
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler scheduler = sf.getScheduler();
		// 如果不设置JobFactory,Service注入到Job会报空指针
		scheduler.setJobFactory(myJobFactory);
		// 启动调度器
		scheduler.start();

		for (SysJob sysJob:jobList) {
			String jobClassName=sysJob.getJobName();
			String jobGroupName=sysJob.getJobGroup();
			//构建job信息
			JobDetail jobDetail = JobBuilder.newJob(getClass(sysJob.getJobClassPath()).getClass()).withIdentity(jobClassName, jobGroupName).build();
			if (StringUtils.isNotEmpty(sysJob.getJobDataMap())) {
				JSONObject jb = JSONObject.parseObject(sysJob.getJobDataMap());
				Map<String, Object> dataMap = (Map<String, Object>)jb.get("data");
				for (Map.Entry<String, Object> m:dataMap.entrySet()) {
					jobDetail.getJobDataMap().put(m.getKey(),m.getValue());
				}
			}
			//表达式调度构建器(即任务执行的时间)
	        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(sysJob.getJobCron());
	        //按新的cronExpression表达式构建一个新的trigger
	        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName, jobGroupName)
	            .withSchedule(scheduleBuilder).startNow().build();
	        // 任务不存在的时候才添加
	        if( !scheduler.checkExists(jobDetail.getKey()) ){
		        try {
		        	scheduler.scheduleJob(jobDetail, trigger);
		        } catch (SchedulerException e) {
		        	logger.info("\n创建定时任务失败"+e);
		            throw new Exception("创建定时任务失败");
		        }
	        }
		}
	}
	
	public static BaseJob getClass(String classname) throws Exception
	{
		Class<?>  c= Class.forName(classname);
		return (BaseJob)c.newInstance();
	}
}


8、自定义JobFactory,使Task注册为Bean

/**
 *
 * 将Spring的对象注入到Quartz Job 1
 */
public class AdaptableJobFactory implements JobFactory {
	@Override
	public Job newJob(TriggerFiredBundle bundle, Scheduler arg1) throws SchedulerException {
		 return newJob(bundle);
	}

	 public Job newJob(TriggerFiredBundle bundle) throws SchedulerException {
	        try {
	        	// 返回Job实例
	            Object jobObject = createJobInstance(bundle);
	            return adaptJob(jobObject);
	        }
	        catch (Exception ex) {
	            throw new SchedulerException("Job instantiation failed", ex);
	        }
	    }

	    // 通过反射的方式创建实例
	    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
	        Method getJobDetail = bundle.getClass().getMethod("getJobDetail");
	        Object jobDetail = ReflectionUtils.invokeMethod(getJobDetail, bundle);
	        Method getJobClass = jobDetail.getClass().getMethod("getJobClass");
	        Class jobClass = (Class) ReflectionUtils.invokeMethod(getJobClass, jobDetail);
	        return jobClass.newInstance();
	    }

	    protected Job adaptJob(Object jobObject) throws Exception {
	        if (jobObject instanceof Job) {
	            return (Job) jobObject;
	        }
	        else if (jobObject instanceof Runnable) {
	            return new DelegatingJob((Runnable) jobObject);
	        }
	        else {
	            throw new IllegalArgumentException("Unable to execute job class [" + jobObject.getClass().getName() +
	                    "]: only [org.quartz.Job] and [java.lang.Runnable] supported.");
	        }
	    }
}
/**
 *
 * 将Spring的对象注入到Quartz Job 2
 */
@Component
public class MyJobFactory extends AdaptableJobFactory {
    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;

    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        //调用父类的方法
        Object jobInstance = super.createJobInstance(bundle);
        // 使我们的JOB注入到Spring容器
        capableBeanFactory.autowireBean(jobInstance);

        return jobInstance;
    }
}

9、省略的内容

此处省略了SysJob实体类,以及Mapper等对数据库的操作。

10、总结

本文只是大致实现一个基于Quartz实现定时任务的动态调度,具体细节还有很多未完善的。自己实现一个任务调度器的话,非常麻烦细节很多。
实现任务调度,推荐使用xxl-job分布式任务调度,或者Elastic-job。

如果需求实在是想要动态的创建任务,修改任务,那么目前为止我还没有更好的办法,只能参考该文章了。文章来源地址https://www.toymoban.com/news/detail-609715.html

到了这里,关于Quartz实战:基于Quartz实现定时任务的动态调度,实现定时任务的增删改查的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring Boot集成Quartz实现定时任务的动态创建、启动、暂停、恢复、删除

    一、整个 Quartz 的代码流程基本基本如下: 首先需要创建我们的任务(Job),比如取消订单、定时发送短信邮件之类的,这是我们的任务主体,也是写业务逻辑的地方。 创建任务调度器(Scheduler),这是用来调度任务的,主要用于启动、停止、暂停、恢复等操作,也就是那几个api的

    2024年02月11日
    浏览(30)
  • STM32 实现简单定时任务调度器,动态创建任务,两种思路实现流水灯

    代码实现和硬件没关系,所以并不限于STM32,Arduino 之类的其他地方也能用,只要有一个能获取时间的函数就行,或者说,只要有一个会随着时间自动增加的变量就行,时间单位无所谓,所以确实想的话,拿到电脑上也能用。后面会用跑马灯程序来说明定时任务的玩法,可以直

    2024年02月10日
    浏览(23)
  • c# 实现Quartz任务调度

    使用 Quartz.NET,你可以很容易地安排任务在应用程序启动时运行,或者每天、每周、每月的特定时间运行,甚至可以基于更复杂的调度规则。 官网:http://www.quartz-scheduler.net/ 创建一个实现了 IJob 接口的类(MailJobTest),该接口包含一个 Execute 方法,该方法将在作业运行时调用。例

    2024年04月11日
    浏览(31)
  • Spring Boot 中实现定时任务(quartz)功能实战

    🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论⭐收藏 🔎 SpringBoot 领域知识 🔎 链接 专栏 SpringBoot 专业知识学习一 SpringBoot专栏 Sprin

    2024年01月19日
    浏览(39)
  • 基于 Quartz.NET 可视化任务调度平台 QuartzUI

    QuartzUI 是基于 Quartz.NET3.0 的定时任务 Web 可视化管理,Docker 打包开箱即用、内置 SQLite 持久化、语言无关、业务代码零污染、支持 RESTful 风格接口、傻瓜式配置、异常请求邮件通知等。 QuartzUI 从 2022 年到现在没有提交记录,这里的部署使用的是最后一个版本的镜像。Windows D

    2024年04月25日
    浏览(20)
  • C#--使用Quartz实现定时任务

    Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等。 Quartz.NET允许开发人员根据时间间隔(或天)来调度作业。它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联。整合了Quartz.NET的应

    2024年02月08日
    浏览(24)
  • 定时任务特辑 | Quartz、xxl-job、elastic-job、Cron四个定时任务框架对比,和Spring Boot集成实战

    专栏集锦,大佬们可以收藏以备不时之需: Spring Cloud 专栏: Python 专栏: Redis 专栏: TensorFlow 专栏: Logback 专栏: 量子计算: 量子计算 | 解密著名量子算法Shor算法和Grover算法 AI机器学习实战: AI机器学习实战 | 使用 Python 和 scikit-learn 库进行情感分析 AI机器学习 | 基于lib

    2024年02月05日
    浏览(42)
  • Quartz + SpringBoot 实现定时任务(多任务,多执行时间)代码模板(直接CV即可)

    quartz 是一款开源且丰富特性的Java 任务调度库 ,用于实现任务调度和定时任务。它支持各种任务类型和灵活的配置选项,具备作业持久化、集群和分布式调度、错误处理和重试机制等功能。Quartz被广泛应用于各种应用程序中,提供可靠和灵活的任务调度解决方案。 我们想要

    2024年02月08日
    浏览(34)
  • ASP.NET Core MVC+Quartz实现定时任务可视化管理页面

    在前一篇文章,我们了解了如何通过.NET6+Quartz开发基于控制台应用程序的定时任务,今天继续在之前的基础上,进一步讲解基于ASP.NET Core MVC+Quartz实现定时任务的可视化管理页面,仅供学习分享使用,如有不足之处,还请指正。 Quartz组件,关于Quartz组件的基本介绍,可参考前

    2024年02月01日
    浏览(34)
  • Spring Boot进阶(69):轻松实现定时任务持久化!SpringBoot集成quartz带你玩转定时任务删除、暂停、获取等操作!【附项目源码】

            现如今,随着市场竞争加剧,各个企业都在不断寻求提高效率、降低成本的方法,此时使用自动化工具已成为必不可少的选择。而在众多的自动化工具中,定时任务已经成为一项必备工具,而Quartz就是一个非常好用的定时任务框架,它的轻量级、高可靠性、易于使

    2024年02月09日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包