quartz定时器的使用,定时任务的动态增删改

目录

一、简介:

二、使用:

1.添加maven依赖包:

2.编写任务bean,主要封装了定时任务相关的信息

3.编写quartz工具类,实现了一个任务的新增,修改执行时间,暂停,恢复等等

4.编写自定义的Job,这里面写要定时执行的任务(我这里利用反射去执行ScheduleJob中封装的方法)

5.扩展工具类

三、测试:


一、简介:

Java的定时任务通常使用以下方式:

  • 使用JDK自带的Timer
  • 使用quartz框架

这里主要是使用quartz来实现。Quartz是一款性能强大的定时任务调度器。开发人员可以使用Quartz让任务在特定时间特定阶段进行运行。Quartz提供两种类型的任务触发方式,一种是按指定时间间隔触发任务,另一种是按指定日历时间触发任务。

二、使用:

1.添加maven依赖包:

<!-- Quartz -->
<dependency>
	<groupId>org.quartz-scheduler</groupId>
	<artifactId>quartz</artifactId>
	<version>2.3.0</version>
</dependency>
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz-jobs</artifactId>
    <version>2.3.0</version>
</dependency>

2.编写任务bean,主要封装了定时任务相关的信息

package cn.zzs.entity;

/**
 * 封装Job信息
 */
public class ScheduleJob {
	/** job名称 **/
	private String jobName;
	
	/** job组 **/
	private String jobGroupName = "QUARTZ_JOB_GROUP";// 默认组名
	
	/** trigger名称 **/
	private String triggerName;// 未赋值时默认返回jobName
	
	/** jtrigger组 **/
	private String triggerGroupName = "QUARTZ_TRIGGER_GROUP";// 默认组名

	/** cron时间表达式 **/
	private String cronExpression;

	/** 任务执行的类名:service类名 **/
	private String springId;

	/** 任务执行的类名:包名+类名 **/
	private String beanClass;

	/** 任务执行的方法名 **/
	private String methodName;

	/** 是否自定义 **/
	private String isZdy = "n";// 反射时默认不指定参数类型

	public String getTriggerName() {
		if(triggerName == null || "".equals(triggerName)) {
			return jobName;
		}else {
			return triggerName;
		}
	}

	// 其他getter/setter方法省略
}

3.编写quartz工具类,实现了一个任务的新增,修改执行时间,暂停,恢复等等

package cn.zzs.utils;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;

import cn.zzs.entity.ScheduleJob;

/**
 * quzrtz工具类
 */
public class QuartzManager {
	
	private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();

	/**
	 *  添加一个定时任务
	 */
	public static void addJob(ScheduleJob scheduleJob) {
		try {
			Scheduler scheduler = schedulerFactory.getScheduler();
			// 任务名,任务组,任务执行类
			JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class)
					.withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroupName())
					.build();
			jobDetail.getJobDataMap().put("scheduleJob", scheduleJob); //JobDataMap可用于保存任何您希望在执行时对作业实例可用的数据对象
			
			// 触发器
			CronTrigger trigger = TriggerBuilder.newTrigger()
					.withIdentity(scheduleJob.getTriggerName(), scheduleJob.getTriggerGroupName())
					.withSchedule(CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()))
					.build();
			// 调度容器设置JobDetail和Trigger
			scheduler.scheduleJob(jobDetail, trigger);
			// 启动
			if (!scheduler.isShutdown()) {
				scheduler.start();
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 修改一个任务的触发时间
	 */
	public static void modifyJobTime(ScheduleJob scheduleJob) {
		try {
			Scheduler scheduler = schedulerFactory.getScheduler();
			TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getTriggerName(), scheduleJob.getTriggerGroupName());
			CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
			if (trigger == null) {
				return;
			}
			String oldTime = trigger.getCronExpression();
			if (!oldTime.equalsIgnoreCase(scheduleJob.getCronExpression())) {
				trigger = //TriggerBuilder.newTrigger()
						trigger.getTriggerBuilder()
						.withIdentity(triggerKey)
						.withSchedule(CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()))
						.build();
				// 修改一个任务的触发时间
				scheduler.rescheduleJob(triggerKey, trigger);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 暂停一个任务
	 */
	public static void pauseJob(ScheduleJob scheduleJob) {
		try {
			Scheduler scheduler = schedulerFactory.getScheduler();
			JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroupName());
			scheduler.pauseJob(jobKey);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 恢复一个任务
	 */
	public static void resumeJob(ScheduleJob scheduleJob) {
		try {
			Scheduler scheduler = schedulerFactory.getScheduler();
			JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroupName());
			scheduler.resumeJob(jobKey);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 立即执行一个任务
	 * 
	 * 说明:
	 * 		这里的立即运行,只会运行一次,方便测试时用。
	 * 		quartz是通过临时生成一个trigger的方式来实现的,这个trigger将在本次任务运行完成之后自动删除。
	 */
	public static void triggerJob(ScheduleJob scheduleJob) {
		try {
			Scheduler scheduler = schedulerFactory.getScheduler();
			JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroupName());
			scheduler.triggerJob(jobKey);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 移除一个任务
	 */
	public static void removeJob(ScheduleJob scheduleJob) {
		try {
			Scheduler scheduler = schedulerFactory.getScheduler();

			TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getTriggerName(), scheduleJob.getTriggerGroupName());
			// 停止触发器
			scheduler.pauseTrigger(triggerKey);
			// 移除触发器
			scheduler.unscheduleJob(triggerKey);
			// 删除任务
			scheduler.deleteJob(JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroupName()));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 
	 * 启动所有定时任务
	 */
	public static void startJobs() {
		try {
			Scheduler scheduler = schedulerFactory.getScheduler();
			scheduler.start();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 关闭所有定时任务
	 */
	public static void shutdownJobs() {
		try {
			Scheduler scheduler = schedulerFactory.getScheduler();
			if (!scheduler.isShutdown()) {
				scheduler.shutdown();
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

}

4.编写自定义的Job,这里面写要定时执行的任务(我这里利用反射去执行ScheduleJob中封装的方法

package cn.zzs.utils;

import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import cn.zzs.entity.ScheduleJob;

/**
 * Job实现类:
 * 		计划任务执行处(反射执行)
 */
public class QuartzJobFactory implements Job {
	public final Logger log = Logger.getLogger(this.getClass());

	/**
	 * 这个方法里写需要定时执行的任务
	 * 		我这里已经将需要执行的类名和方法名封装进ScheduleJob中,因此此方法利用反射获取ScheduleJob中的信息去执行
	 */
	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		// 获取创建Job时传递的数据
		ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
		// 利用反射去执行
		ScheduleJobUtils.invokMethod(scheduleJob);
	}
}

5.扩展工具类

package cn.zzs.utils;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import cn.zzs.entity.ScheduleJob;

/**
 * Job执行工具类,利用反射执行相应的类的对应方法
 */
public class ScheduleJobUtils {
	
	public final static Logger log = Logger.getLogger(ScheduleJobUtils.class);

	/**
	 * 通过反射调用scheduleJob中定义的方法
	 */
	public static void invokMethod(ScheduleJob scheduleJob) {
		Object object = null;
		Class<?> clazz = null;
		if (StringUtils.isNotBlank(scheduleJob.getSpringId())) {
			object = SpringUtils.getBean(scheduleJob.getSpringId());
			clazz = object.getClass();
		} else if (StringUtils.isNotBlank(scheduleJob.getBeanClass())) {
			try {
				clazz = Class.forName(scheduleJob.getBeanClass());
				object = clazz.newInstance();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if (object == null) {
			log.error(getNow() + " >任务名称 = [" + scheduleJob.getJobName() + "]--------未启动成功,请检查是否配置正确!!!");
			return;
		}
		
		try {
			// 如果是自定义任务
			if ("y".equals(scheduleJob.getIsZdy())) {
				Method method = clazz.getDeclaredMethod(scheduleJob.getMethodName(), new Class[] { ScheduleJob.class });
				method.invoke(object, scheduleJob);
			} else {
				Method method = clazz.getDeclaredMethod(scheduleJob.getMethodName(), new Class[] {});
				method.invoke(object, new Object[] {});
			}
		} catch (Exception e) {
			log.error(getNow() + " >任务名称 = [" + scheduleJob.getJobName() + "]--------未启动成功,方法名设置错误!!!");
		} 
		
		log.info(getNow() + " >任务名称 = [" + scheduleJob.getJobName() + "]--------启动成功");
	}

	/**
	 * 获取当前的时间字符串 ,格式为yyyy-MM-dd HH:mm:ss.SSS
	 */
	private static String getNow() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		return sdf.format(new Date());
	}
}

三、测试:

package cn.zzs.test;

import java.text.SimpleDateFormat;
import java.util.Date;

import cn.zzs.entity.ScheduleJob;
import cn.zzs.utils.QuartzManager;

public class MyTest {
	
	public static void main(String[] args) {
		ScheduleJob scheduleJob = new ScheduleJob();
		scheduleJob.setJobName("00");
		scheduleJob.setJobGroupName("TEST");
		scheduleJob.setTriggerName("00");
		scheduleJob.setTriggerGroupName("TEST");
		scheduleJob.setBeanClass("cn.zzs.test.MyTest");
		scheduleJob.setMethodName("show");
		scheduleJob.setCronExpression("0/1 * * * * ?");// 每秒钟执行一次
		
		QuartzManager.addJob(scheduleJob);
		
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		
		/*
		 * 测试修改任务时间
		 */
		scheduleJob.setCronExpression("0/30 * * * * ?");// 每30秒执行一次
		QuartzManager.modifyJobTime(scheduleJob);
	}
	
	public void show() {
		System.err.println(getNow());// 打印当前时间
	}
	
	private String getNow() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		return sdf.format(new Date());
	}
}

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值