|
Quartz 实现动态管理任务
1.Quartz实现动态管理任务
1.1.需求目标
基于Quartz原生API,进行定时任务的动态管理,实现任务的添加、删除、暂停、继续以及任务调度时间的修改。
1.2.纯Java代码实现
1.新建Maven项目,并引入依赖,pom.xml的内容如下:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.itcast.quartz</groupId>
<artifactId>quartzmanager</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!-- quartz核心 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
</dependency>
<!-- slf4j log4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
<!-- junit测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
2.创建工作对象
public class QuartzManager {
//用于创建Scheduler的工厂对象。默认情况下是加载当前工作目录下的”quartz.properties”属性文件。如果加载失败,会去加载org/quartz包下的”quartz.properties”属性文件。
private static SchedulerFactory schedulerFactory=new StdSchedulerFactory();
/**
* 启动作业调度(所有定时任务)
*/
public static void startScheduler() {
try {
//获取调度程序对象,单例
Scheduler scheduler = schedulerFactory.getScheduler();
//判断是否已经启动了
if(!scheduler.isStarted()) {
//如果没有启动,则启动
scheduler.start();
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 关闭作业调度(所有定时任务)
*/
public static void shutdownScheduler() {
try {
//获取调度程序对象,单例
Scheduler scheduler = schedulerFactory.getScheduler();
//判断是否已经关闭了
if(!scheduler.isShutdown()) {
//如果没有关闭,则关闭
scheduler.shutdown();
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 添加一个定时任务
* @param jobName 任务名字
* @param jobGroupName 任务组名
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
* @param jobClass 任务工作(具体执行)对象的类
* @param cron 计划任务表达式
*/
public static void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class jobClass,String cron) {
//获取调度程序对象,单例
try {
Scheduler scheduler = schedulerFactory.getScheduler();
//1. 创建任务对象
JobDetail jobDetail=
//指定任务工作(具体执行)类
JobBuilder.newJob(jobClass)
//2)使用指定的任务名字和任务组名字来构成JobKey,作为任务的唯一标识。
.withIdentity(jobName,jobGroupName)
.build();
//2. 创建触发器对象
//触发器任务计划执行表的执行”机制”。多个触发器可以指向同一个工作,但一个触发器只能指向一个工作
Trigger trigger=TriggerBuilder.newTrigger()
//使用指定的触发器名字和触发器组名字来构成TriggerKey,作为触发器的唯一标识。
.withIdentity(triggerName, triggerGroupName)
.withSchedule(
CronScheduleBuilder.cronSchedule(cron)
)
.build();
//3. 作业调度容器设置任务对象和触发器对象
scheduler.scheduleJob(jobDetail, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 通过Cron表达式来修改一个定时任务的触发时间。方式一:直接调用rescheduleJob方法
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
* @param cron 计划任务表达式
*/
public static void modifyJobTimeByCron(String triggerName, String triggerGroupName, String cron) {
//获取调度程序对象,单例
try {
Scheduler scheduler = schedulerFactory.getScheduler();
//1. 判断某触发器是否存在
TriggerKey triggerKey=TriggerKey.triggerKey(triggerName, triggerGroupName);
CronTrigger oldTrigger = (CronTrigger)scheduler.getTrigger(triggerKey);
if(oldTrigger==null) {
//如果触发器不存在,则返回
return;
}
//2.
//获取之前触发器的计划任务表达式
String oldCronExpression = oldTrigger.getCronExpression();
//判断新旧表达式是否一样
if(!oldCronExpression.equalsIgnoreCase(cron)) {
//-----方式一:直接调用rescheduleJob方法
//如果不一样,则创建一个新的触发器对象
Trigger newTrigger=TriggerBuilder.newTrigger()
//使用指定的触发器名字和触发器组名字来构成TriggerKey,作为触发器的唯一标识。
.withIdentity(triggerName, triggerGroupName)
.withSchedule(
CronScheduleBuilder.cronSchedule(cron)
)
.build();
//该方法先根据triggerKey删除旧的任务,再添加保存新的任务,要求必须是job一样。
Date firstFireTimeOfNewTrigger = scheduler.rescheduleJob(triggerKey, newTrigger);
if(firstFireTimeOfNewTrigger==null) {
System.out.println("修改失败!");
}
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 通过Cron表达式来修改一个定时任务的触发时间:方式二:先手动删除旧的任务,再手动创建新的任务
* @param jobName 任务名字
* @param jobGroupName 任务组名
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
* @param cron 计划任务表达式
*/
public static void modifyJobTimeByCron2 (String jobName, String jobGroupName, String triggerName, String triggerGroupName, String cron) {
//获取调度程序对象,单例
try {
Scheduler scheduler = schedulerFactory.getScheduler();
//1. 判断某触发器是否存在
TriggerKey triggerKey=TriggerKey.triggerKey(triggerName, triggerGroupName);
CronTrigger oldTrigger = (CronTrigger)scheduler.getTrigger(triggerKey);
if(oldTrigger==null) {
//如果触发器不存在,则返回
return;
}
//2.
//获取之前触发器的计划任务表达式
String oldCronExpression = oldTrigger.getCronExpression();
//判断新旧表达式是否一样
if(!oldCronExpression.equalsIgnoreCase(cron)) {
//-----方式二:先手动删除旧的任务,再手动创建新的任务
JobKey jobKey=JobKey.jobKey(jobName, jobGroupName);
JobDetail oldJobDetail = scheduler.getJobDetail(jobKey);
Class<? extends Job> jobClass = oldJobDetail.getJobClass();
removeJob(jobName, jobGroupName, triggerName, triggerGroupName);
addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron);
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 删除(移除)一个任务
* @param jobName
* @param jobGroupName
* @param triggerName
* @param triggerGroupName
*/
public static void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) {
//获取调度程序对象,单例
try {
Scheduler scheduler = schedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
scheduler.pauseTrigger(triggerKey);// 停止触发器
scheduler.unscheduleJob(triggerKey);// 移除触发器
scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 删除任务
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 暂停某任务的触发器
* @param triggerName
* @param triggerGroupName
*/
public static void pauseTrigger(String triggerName, String triggerGroupName) {
try {
Scheduler scheduler = schedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
scheduler.pauseTrigger(triggerKey);// 停止触发器
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 恢复某任务的触发器
* @param triggerName
* @param triggerGroupName
*/
public static void resumeTrigger(String triggerName, String triggerGroupName) {
try {
Scheduler scheduler = schedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
scheduler.resumeTrigger(triggerKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 暂停某任务的执行(底层仍然是暂停触发器)
* @param jobName
* @param jobGroupName
*/
public static void pauseJob(String jobName, String jobGroupName) {
try {
Scheduler scheduler = schedulerFactory.getScheduler();
JobKey jobKey=JobKey.jobKey(jobName, jobGroupName);
scheduler.pauseJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 恢复某任务的执行(底层仍然是恢复触发器)
* @param jobName
* @param jobGroupName
*/
public static void resumeJob(String jobName, String jobGroupName) {
try {
Scheduler scheduler = schedulerFactory.getScheduler();
JobKey jobKey=JobKey.jobKey(jobName, jobGroupName);
scheduler.resumeJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
3.junit测试
public class QuartzTest {
public static String JOB_NAME = "HelloJob";
public static String TRIGGER_NAME = "HelloTrigger";
public static String JOB_GROUP_NAME = "HELLO_JOB_GROUP";
public static String TRIGGER_GROUP_NAME = "HELLO_JOB_GROUP";
@Test
public void test() throws Exception {
System.out.println("【系统启动】开始...");
QuartzManager.startScheduler();
System.out.println("【系统启动】成功...");
Thread.sleep(5000);
System.out.println("开始(每1秒输出一次)...");
QuartzManager.addJob(JOB_NAME, JOB_GROUP_NAME, TRIGGER_NAME, TRIGGER_GROUP_NAME, HelloJob.class, "0/1 * * * * ?");
Thread.sleep(5000);
System.out.println("执行了5秒后,定时器暂停执行3秒...");
QuartzManager.pauseTrigger(TRIGGER_NAME, TRIGGER_GROUP_NAME);
Thread.sleep(3000);
System.out.println("定时器恢复执行...");
QuartzManager.resumeTrigger(TRIGGER_NAME, TRIGGER_GROUP_NAME);
Thread.sleep(5000);
System.out.println("【修改时间】开始(每5秒输出一次)...");
QuartzManager.modifyJobTimeByCron(TRIGGER_NAME, TRIGGER_GROUP_NAME, "0/5 * * * * ?");
Thread.sleep(6000);
System.out.println("【移除定时】开始...");
QuartzManager.removeJob(JOB_NAME, JOB_GROUP_NAME, TRIGGER_NAME, TRIGGER_GROUP_NAME);
System.out.println("【移除定时】成功");
Thread.sleep(5000);
QuartzManager.shutdownScheduler();
System.out.println("【系统关闭】...");
}
} |