国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Quartz實戰(zhàn):基于Quartz實現(xiàn)定時任務(wù)的動態(tài)調(diào)度,實現(xiàn)定時任務(wù)的增刪改查

這篇具有很好參考價值的文章主要介紹了Quartz實戰(zhàn):基于Quartz實現(xiàn)定時任務(wù)的動態(tài)調(diào)度,實現(xiàn)定時任務(wù)的增刪改查。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、Quartz基礎(chǔ)

Quartz使用文檔,使用Quartz實現(xiàn)動態(tài)任務(wù),Spring集成Quartz,Quartz集群部署,Quartz源碼分析

二、使用Quartz實現(xiàn)定時任務(wù)的動態(tài)調(diào)度

1、使用Quartz-jobStore 持久化

Quartz使用文檔,使用Quartz實現(xiàn)動態(tài)任務(wù),Spring集成Quartz,Quartz集群部署,Quartz源碼分析

2、前端頁面實現(xiàn)效果圖

Quartz實戰(zhàn):基于Quartz實現(xiàn)定時任務(wù)的動態(tài)調(diào)度,實現(xiàn)定時任務(wù)的增刪改查,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 '任務(wù)名稱',
  `job_group` varchar(512) NOT NULL COMMENT '任務(wù)組名',
  `job_cron` varchar(512) NOT NULL COMMENT '時間表達式',
  `job_class_path` varchar(1024) NOT NULL COMMENT '類路徑,全類型',
  `job_data_map` varchar(1024) DEFAULT NULL COMMENT '傳遞map參數(shù)',
  `job_status` int(2) NOT NULL COMMENT '狀態(tài):1啟用 0停用',
  `job_describe` varchar(1024) DEFAULT NULL COMMENT '任務(wù)功能描述',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8;

-- 插入3條數(shù)據(jù),3個任務(wù)
-- 注意第三條,是一個發(fā)送郵件的任務(wù),需要改成你自己的QQ和授權(quán)碼。不知道什么是授權(quán)碼的自己百度。
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\":\"改成你的郵箱授權(quán)碼\",\"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";
	}

	/**
	 * 查詢?nèi)蝿?wù)列表(帶分頁)
	 * 
	 * @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("數(shù)據(jù)請求成功");
			layuiData.setData(jobList);
			return layuiData;
		} catch (Exception e) {
			throw new BizException("查詢?nèi)蝿?wù)列表異常:" + e.getMessage());
		}
	}

	/**
	 * 添加定時任務(wù)
	 *
	 * @throws Exception
	 */
	@PostMapping(value = "/addJob")
	@ResponseBody
	@Transactional
	public int addjob(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("添加任務(wù)開始... ...");
		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("任務(wù)名稱不能為空");
		}
		if (StringUtils.isBlank(jobGroup)) {
			throw new BizException("任務(wù)組別不能為空");
		}
		if (StringUtils.isBlank(jobCron)) {
			throw new BizException("Cron表達式不能為空");
		}
		if (StringUtils.isBlank(jobClassPath)) {
			throw new BizException("任務(wù)類路徑不能為空");
		}
		
		// 參數(shù)不為空時校驗格式
		if(StringUtils.isNotBlank(jobDataMap)){
			try {
				JSONObject.parseObject(jobDataMap);
			} catch (Exception e) {
				throw new BizException("參數(shù)JSON格式錯誤");
			}
		}
		
		// 已存在校驗
		SysJob queryBean = new SysJob();
		queryBean.setJobName(jobName);
		SysJob result = sysJobService.selectByBean(queryBean);
		if (null != result) {
			throw new BizException("任務(wù)名為" + jobName + "的任務(wù)已存在!");
		}

		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("新增定時任務(wù)失敗");
		}
		
		SchedulerUtil.addJob(jobClassPath,jobName, jobGroup, jobCron,jobDataMap);
		return num;
	}
	
	/**
	 * 變更定時任務(wù)執(zhí)行狀態(tài)
	 * @return
	 * @throws Exception
	 */
	@GetMapping(value = "/changeState")
	@ResponseBody
	public int changeState(@RequestParam(value = "id") String idStr)throws Exception{
        logger.info("變更定時任務(wù)狀態(tài)開始... ...");
		if (StringUtils.isBlank(idStr)) {
			throw new BizException("任務(wù)ID不能為空");
		}
		int id = Integer.parseInt(idStr);

		// 校驗
		SysJob queryBean = new SysJob();
		queryBean.setId(id);
		SysJob result = sysJobService.selectByBean(queryBean);
		if (null == result) {
			throw new BizException("任務(wù)ID為" + id + "的任務(wù)不存在!");
		}
		
		SysJob updateBean = new SysJob();
		updateBean.setId(id);
		//如果是現(xiàn)在是啟用,則停用
		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());
		  }
		}
		
		//如果現(xiàn)在是停用,則啟用
		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("更新數(shù)據(jù)庫的定時任務(wù)信息異常!");
		}
		// 1表示成功
		return 1;
		
	}

	/**
	 * 刪除一個任務(wù)
	 *
	 * @throws Exception
	 */
	@PostMapping(value = "/deleteJob")
	@ResponseBody
	public int deletejob(@RequestParam(value = "id") String idStr) throws Exception {
        logger.info("刪除定時任務(wù)狀態(tài)開始... ...");
		int num =0;
		if (StringUtils.isBlank(idStr)) {
			throw new BizException("任務(wù)ID不能為空");
		}
		int id = Integer.parseInt(idStr);
		
		// 存在性校驗
		SysJob queryBean = new SysJob();
		queryBean.setId(id);
		SysJob result = sysJobService.selectByBean(queryBean);
		if (null == result) {
			throw new BizException("任務(wù)ID為" + idStr + "的任務(wù)不存在!");
		}
		
		try {
			num = sysJobService.deleteByPrimaryKey(id);
		} catch (Exception e) {
			throw new BizException("從數(shù)據(jù)庫刪除定時任務(wù)時發(fā)生異常!");
		}
		
		SchedulerUtil.jobdelete(result.getJobName(), result.getJobGroup());
		return num;
	}

	/**
	 * 修改定時表達式
	 */
	@RequestMapping("/reSchedulejob")
	@ResponseBody
	public int updateByBean(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("修改定時任務(wù)信息開始... ...");
		int num =0;
		String jobCron = request.getParameter("jobCron");
		String jobDescribe = request.getParameter("jobDescribe");
		String idStr = request.getParameter("id");
		int id = Integer.parseInt(idStr);
		// 數(shù)據(jù)非空校驗
		if (!StringUtils.isNotBlank(idStr)) {
			throw new BizException("任務(wù)ID不能為空");
		}
		SysJob result = sysJobService.selectByPrimaryKey(id);
		// 數(shù)據(jù)不存在
		if (null == result) {
			throw new BizException("根據(jù)任務(wù)ID[" + id + "]未查到相應(yīng)的任務(wù)記錄");
		}
		SysJob bean = new SysJob();
		bean.setId(id);
		bean.setJobCron(jobCron);
		bean.setJobDescribe(jobDescribe);
		try {
			num = sysJobService.updateByPrimaryKeySelective(bean);
		} catch (Exception e) {
			throw new BizException("變更任務(wù)表達式異常:" + e.getMessage());
		}
		//只有任務(wù)狀態(tài)為啟用,才開始運行
		// 如果先啟動再手工插入數(shù)據(jù),此處會報空指針異常
		if( result.getJobStatus() ==Constant.JOB_STATE.YES ){
			SchedulerUtil.jobReschedule(result.getJobName(), result.getJobGroup(),jobCron);
		}
		
		// 返回成功
		return num;
	}

	/**
	 * 展示任務(wù)調(diào)度管理頁
	 * 
	 * @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);

	/**
	 * 新增定時任務(wù)
	 * @param jobClassName 類路徑
	 * @param jobName 任務(wù)名稱
	 * @param jobGroupName 組別
	 * @param cronExpression Cron表達式
	 * @param jobDataMap 需要傳遞的參數(shù)
	 * @throws Exception
	 */
	public static void addJob(String jobClassName,String jobName, String jobGroupName, String cronExpression,String jobDataMap) throws Exception {
		// 通過SchedulerFactory獲取一個調(diào)度器實例
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler scheduler = sf.getScheduler();
		// 啟動調(diào)度器
		scheduler.start();
		// 構(gòu)建job信息
		JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass())
				.withIdentity(jobName, jobGroupName).build();
		// JobDataMap用于傳遞任務(wù)運行時的參數(shù),比如定時發(fā)送郵件,可以用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());
			}
		}
		// 表達式調(diào)度構(gòu)建器(即任務(wù)執(zhí)行的時間)
		CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
		// 按新的cronExpression表達式構(gòu)建一個新的trigger
		CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
				.withSchedule(scheduleBuilder).startNow().build();
		try {
			scheduler.scheduleJob(jobDetail, trigger);
		} catch (SchedulerException e) {
			logger.info("創(chuàng)建定時任務(wù)失敗" + e);
			throw new Exception("創(chuàng)建定時任務(wù)失敗");
		}
	}
	
	/**
	 * 停用一個定時任務(wù)
	 * @param jobName 任務(wù)名稱
	 * @param jobGroupName 組別
	 * @throws Exception
	 */
	public static void jobPause(String jobName, String jobGroupName) throws Exception {
		// 通過SchedulerFactory獲取一個調(diào)度器實例
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler scheduler = sf.getScheduler();
		scheduler.pauseJob(JobKey.jobKey(jobName, jobGroupName));
	}
	
	/**
	 * 啟用一個定時任務(wù)
	 * @param jobName 任務(wù)名稱
	 * @param jobGroupName 組別
	 * @throws Exception
	 */
	public static void jobresume(String jobName, String jobGroupName) throws Exception {
		// 通過SchedulerFactory獲取一個調(diào)度器實例
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler scheduler = sf.getScheduler();
		scheduler.resumeJob(JobKey.jobKey(jobName, jobGroupName));
	}
	
	/**
	 * 刪除一個定時任務(wù)
	 * @param jobName 任務(wù)名稱
	 * @param jobGroupName 組別
	 * @throws Exception
	 */
	public static void jobdelete(String jobName, String jobGroupName) throws Exception {
		// 通過SchedulerFactory獲取一個調(diào)度器實例
		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));
	}
	
	/**
	 * 更新定時任務(wù)表達式
	 * @param jobName 任務(wù)名稱
	 * @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);
			// 表達式調(diào)度構(gòu)建器
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
			CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
			// 按新的cronExpression表達式重新構(gòu)建trigger
			trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).startNow().build();
			// 按新的trigger重新設(shè)置job執(zhí)行
			scheduler.rescheduleJob(triggerKey, trigger);
		} catch (SchedulerException e) {
			System.out.println("更新定時任務(wù)失敗" + e);
			throw new Exception("更新定時任務(wù)失敗");
		}
	}
	
	/**
	 * 檢查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;
	}

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

	/**
	 * 喚醒所有任務(wù)
	 * @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、測試任務(wù)類

@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("開始執(zhí)行任務(wù)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("沒有狀態(tài)為可用的發(fā)送郵件任務(wù)... ...");
        }

        for (SysJob sysJob:jobList) {
                logger.info("開始發(fā)送郵件... ...");
        }
    }
}

7、springboot啟動初始化定時任務(wù)

/**
 * 這個類用于啟動SpringBoot時,加載作業(yè)。run方法會自動執(zhí)行。
 *
 * 另外可以使用 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 {
		/**
		 * 用于程序啟動時加載定時任務(wù),并執(zhí)行已啟動的定時任務(wù)(只會執(zhí)行一次,在程序啟動完執(zhí)行)
		 */
		
		//查詢job狀態(tài)為啟用的
		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("系統(tǒng)啟動,沒有需要執(zhí)行的任務(wù)... ...");
		}
		// 通過SchedulerFactory獲取一個調(diào)度器實例
		SchedulerFactory sf = new StdSchedulerFactory();
		Scheduler scheduler = sf.getScheduler();
		// 如果不設(shè)置JobFactory,Service注入到Job會報空指針
		scheduler.setJobFactory(myJobFactory);
		// 啟動調(diào)度器
		scheduler.start();

		for (SysJob sysJob:jobList) {
			String jobClassName=sysJob.getJobName();
			String jobGroupName=sysJob.getJobGroup();
			//構(gòu)建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());
				}
			}
			//表達式調(diào)度構(gòu)建器(即任務(wù)執(zhí)行的時間)
	        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(sysJob.getJobCron());
	        //按新的cronExpression表達式構(gòu)建一個新的trigger
	        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName, jobGroupName)
	            .withSchedule(scheduleBuilder).startNow().build();
	        // 任務(wù)不存在的時候才添加
	        if( !scheduler.checkExists(jobDetail.getKey()) ){
		        try {
		        	scheduler.scheduleJob(jobDetail, trigger);
		        } catch (SchedulerException e) {
		        	logger.info("\n創(chuàng)建定時任務(wù)失敗"+e);
		            throw new Exception("創(chuàng)建定時任務(wù)失敗");
		        }
	        }
		}
	}
	
	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);
	        }
	    }

	    // 通過反射的方式創(chuàng)建實例
	    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 {
        //調(diào)用父類的方法
        Object jobInstance = super.createJobInstance(bundle);
        // 使我們的JOB注入到Spring容器
        capableBeanFactory.autowireBean(jobInstance);

        return jobInstance;
    }
}

9、省略的內(nèi)容

此處省略了SysJob實體類,以及Mapper等對數(shù)據(jù)庫的操作。

10、總結(jié)

本文只是大致實現(xiàn)一個基于Quartz實現(xiàn)定時任務(wù)的動態(tài)調(diào)度,具體細節(jié)還有很多未完善的。自己實現(xiàn)一個任務(wù)調(diào)度器的話,非常麻煩細節(jié)很多。
實現(xiàn)任務(wù)調(diào)度,推薦使用xxl-job分布式任務(wù)調(diào)度,或者Elastic-job。

如果需求實在是想要動態(tài)的創(chuàng)建任務(wù),修改任務(wù),那么目前為止我還沒有更好的辦法,只能參考該文章了。文章來源地址http://www.zghlxwxcb.cn/news/detail-609715.html

到了這里,關(guān)于Quartz實戰(zhàn):基于Quartz實現(xiàn)定時任務(wù)的動態(tài)調(diào)度,實現(xiàn)定時任務(wù)的增刪改查的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Spring Boot集成Quartz實現(xiàn)定時任務(wù)的動態(tài)創(chuàng)建、啟動、暫停、恢復、刪除

    Spring Boot集成Quartz實現(xiàn)定時任務(wù)的動態(tài)創(chuàng)建、啟動、暫停、恢復、刪除

    一、整個 Quartz 的代碼流程基本基本如下: 首先需要創(chuàng)建我們的任務(wù)(Job),比如取消訂單、定時發(fā)送短信郵件之類的,這是我們的任務(wù)主體,也是寫業(yè)務(wù)邏輯的地方。 創(chuàng)建任務(wù)調(diào)度器(Scheduler),這是用來調(diào)度任務(wù)的,主要用于啟動、停止、暫停、恢復等操作,也就是那幾個api的

    2024年02月11日
    瀏覽(21)
  • STM32 實現(xiàn)簡單定時任務(wù)調(diào)度器,動態(tài)創(chuàng)建任務(wù),兩種思路實現(xiàn)流水燈

    STM32 實現(xiàn)簡單定時任務(wù)調(diào)度器,動態(tài)創(chuàng)建任務(wù),兩種思路實現(xiàn)流水燈

    代碼實現(xiàn)和硬件沒關(guān)系,所以并不限于STM32,Arduino 之類的其他地方也能用,只要有一個能獲取時間的函數(shù)就行,或者說,只要有一個會隨著時間自動增加的變量就行,時間單位無所謂,所以確實想的話,拿到電腦上也能用。后面會用跑馬燈程序來說明定時任務(wù)的玩法,可以直

    2024年02月10日
    瀏覽(21)
  • c# 實現(xiàn)Quartz任務(wù)調(diào)度

    使用 Quartz.NET,你可以很容易地安排任務(wù)在應(yīng)用程序啟動時運行,或者每天、每周、每月的特定時間運行,甚至可以基于更復雜的調(diào)度規(guī)則。 官網(wǎng):http://www.quartz-scheduler.net/ 創(chuàng)建一個實現(xiàn)了 IJob 接口的類(MailJobTest),該接口包含一個 Execute 方法,該方法將在作業(yè)運行時調(diào)用。例

    2024年04月11日
    瀏覽(18)
  • Spring Boot 中實現(xiàn)定時任務(wù)(quartz)功能實戰(zhàn)

    Spring Boot 中實現(xiàn)定時任務(wù)(quartz)功能實戰(zhàn)

    ??作者簡介,普修羅雙戰(zhàn)士,一直追求不斷學習和成長,在技術(shù)的道路上持續(xù)探索和實踐。 ??多年互聯(lián)網(wǎng)行業(yè)從業(yè)經(jīng)驗,歷任核心研發(fā)工程師,項目技術(shù)負責人。 ??歡迎 ??點贊?評論?收藏 ?? SpringBoot 領(lǐng)域知識 ?? 鏈接 專欄 SpringBoot 專業(yè)知識學習一 SpringBoot專欄 Sprin

    2024年01月19日
    瀏覽(24)
  • 基于 Quartz.NET 可視化任務(wù)調(diào)度平臺 QuartzUI

    基于 Quartz.NET 可視化任務(wù)調(diào)度平臺 QuartzUI

    QuartzUI 是基于 Quartz.NET3.0 的定時任務(wù) Web 可視化管理,Docker 打包開箱即用、內(nèi)置 SQLite 持久化、語言無關(guān)、業(yè)務(wù)代碼零污染、支持 RESTful 風格接口、傻瓜式配置、異常請求郵件通知等。 QuartzUI 從 2022 年到現(xiàn)在沒有提交記錄,這里的部署使用的是最后一個版本的鏡像。Windows D

    2024年04月25日
    瀏覽(22)
  • C#--使用Quartz實現(xiàn)定時任務(wù)

    C#--使用Quartz實現(xiàn)定時任務(wù)

    Quartz.NET是一個開源的作業(yè)調(diào)度框架,非常適合在平時的工作中,定時輪詢數(shù)據(jù)庫同步,定時郵件通知,定時處理數(shù)據(jù)等。 Quartz.NET允許開發(fā)人員根據(jù)時間間隔(或天)來調(diào)度作業(yè)。它實現(xiàn)了作業(yè)和觸發(fā)器的多對多關(guān)系,還能把多個作業(yè)與不同的觸發(fā)器關(guān)聯(lián)。整合了Quartz.NET的應(yīng)

    2024年02月08日
    瀏覽(24)
  • 定時任務(wù)特輯 | Quartz、xxl-job、elastic-job、Cron四個定時任務(wù)框架對比,和Spring Boot集成實戰(zhàn)

    定時任務(wù)特輯 | Quartz、xxl-job、elastic-job、Cron四個定時任務(wù)框架對比,和Spring Boot集成實戰(zhàn)

    專欄集錦,大佬們可以收藏以備不時之需: Spring Cloud 專欄: Python 專欄: Redis 專欄: TensorFlow 專欄: Logback 專欄: 量子計算: 量子計算 | 解密著名量子算法Shor算法和Grover算法 AI機器學習實戰(zhàn): AI機器學習實戰(zhàn) | 使用 Python 和 scikit-learn 庫進行情感分析 AI機器學習 | 基于lib

    2024年02月05日
    瀏覽(41)
  • Quartz + SpringBoot 實現(xiàn)定時任務(wù)(多任務(wù),多執(zhí)行時間)代碼模板(直接CV即可)

    Quartz + SpringBoot 實現(xiàn)定時任務(wù)(多任務(wù),多執(zhí)行時間)代碼模板(直接CV即可)

    quartz 是一款開源且豐富特性的Java 任務(wù)調(diào)度庫 ,用于實現(xiàn)任務(wù)調(diào)度和定時任務(wù)。它支持各種任務(wù)類型和靈活的配置選項,具備作業(yè)持久化、集群和分布式調(diào)度、錯誤處理和重試機制等功能。Quartz被廣泛應(yīng)用于各種應(yīng)用程序中,提供可靠和靈活的任務(wù)調(diào)度解決方案。 我們想要

    2024年02月08日
    瀏覽(22)
  • ASP.NET Core MVC+Quartz實現(xiàn)定時任務(wù)可視化管理頁面

    ASP.NET Core MVC+Quartz實現(xiàn)定時任務(wù)可視化管理頁面

    在前一篇文章,我們了解了如何通過.NET6+Quartz開發(fā)基于控制臺應(yīng)用程序的定時任務(wù),今天繼續(xù)在之前的基礎(chǔ)上,進一步講解基于ASP.NET Core MVC+Quartz實現(xiàn)定時任務(wù)的可視化管理頁面,僅供學習分享使用,如有不足之處,還請指正。 Quartz組件,關(guān)于Quartz組件的基本介紹,可參考前

    2024年02月01日
    瀏覽(28)
  • Spring Boot進階(69):輕松實現(xiàn)定時任務(wù)持久化!SpringBoot集成quartz帶你玩轉(zhuǎn)定時任務(wù)刪除、暫停、獲取等操作!【附項目源碼】

    Spring Boot進階(69):輕松實現(xiàn)定時任務(wù)持久化!SpringBoot集成quartz帶你玩轉(zhuǎn)定時任務(wù)刪除、暫停、獲取等操作!【附項目源碼】

    ????????現(xiàn)如今,隨著市場競爭加劇,各個企業(yè)都在不斷尋求提高效率、降低成本的方法,此時使用自動化工具已成為必不可少的選擇。而在眾多的自動化工具中,定時任務(wù)已經(jīng)成為一項必備工具,而Quartz就是一個非常好用的定時任務(wù)框架,它的輕量級、高可靠性、易于使

    2024年02月09日
    瀏覽(31)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包