目录
3.编写quartz工具类,实现了一个任务的新增,修改执行时间,暂停,恢复等等
4.编写自定义的Job,这里面写要定时执行的任务(我这里利用反射去执行ScheduleJob中封装的方法)
一、简介:
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());
}
}