Java定时任务Quartz一

1.概要

      Quartz是由OpenSymphony提供的强大的开源任务调度框架。官网地址:http://www.quartz-scheduler.org/,纯Java实现。

  • 强大的调度功能:很容易与Spring集成,提供调度运行环境的持久化机制,保存并恢复任务调度现场。即使系统因故障关闭,任务调度现场数据也不会丢失;
  • 灵活的应用方式:允许灵活的定义触发器的调度时间表,并可以对触发器和任务进行关联映射,提供了组件式的监听器、各种插件、线程池等功能,支持任务和调度的多种组合方式、支持调度数据的多种存储方式,支持分布式和集群操作;
  • 主要用到的设计模式:Builder模式、Factory模式、组件模式、链式写法;
  • 核心概念:调度器——负责定期、定时、定频率的去执行任务;任务——具体的业务逻辑;触发器——调度器调度任务的时间;
  • 重要组成:Job——接口且可以接收参数;JobDetail——Job的实现类和相关的静态信息;JobBuilder——定义或者创建JobDetail的实例;JobStore——用来保存Job数据;Trigger——描述触发Job执行时的时间触发规则;TriggerBuilder——定义或者创建触发器的实例;ThreadPool——线程池Job运行的基础设施;Scheduler——Quartz独立运行的容器;Calendar——一个Trigger可以和多个Calendar关联,以排除或者包含某些时间点;监听器——JobListener、TriggerListener、SchedulerLIstener监听对应的组件。

2.Quartz的基本使用

1.每两秒钟打印一次Hello World:

创建Job实现类HelloJob

package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class HelloJob implements Job{
	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		//打印当前执行时间
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("任务执行时间为:"+sf.format(startTime));
		System.out.println("Hello World");
	}
}

创建Job测试类HelloScheduler

package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
	public static void main(String[] args) throws SchedulerException {
		// 创建一个JobDetail实例与HelloJob类绑定
		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
		// 创建一个Trigger实例,定义该Job立即执行,且每隔两秒钟执行一次直到永远
		Trigger trigger = TriggerBuilder.newTrigger().withIdentity("mtTrigger", "group1").startNow()
				.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();
		//创建scheduler实例
		SchedulerFactory sFactory = new StdSchedulerFactory();
		Scheduler scheduler = sFactory.getScheduler();
		scheduler.start();
		//打印当前时间
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("打印当前时间:"+sf.format(startTime));
		scheduler.scheduleJob(jobDetail,trigger);
	}
}
2.浅谈Job&JobDetail

     Job:实现业务逻辑的任务接口,job接口非常容易实现,只有一个execute方法,类似TimerTask的run方法,在里面编写业务逻辑。Job在Quartz中的生命周期:每次调度器执行Job时,它在调用execute方法前会创建一个新Job实例;当调用完成后,关联的job对象实例会被释放,释放的实例会被垃圾回收机制回收。JobDetail为job提供了很多设置属性name、group、jobClass、jobDataMap(用来存储特定Job实例的状态信息),调度器需要借助JobDetail对象来添加Job实例。

package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
	public static void main(String[] args) throws SchedulerException {
		// 创建一个JobDetail实例与HelloJob类绑定
		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
		System.out.println("JobDetail's name:"+jobDetail.getKey().getName());
		System.out.println("JobDetail's group:"+jobDetail.getKey().getGroup());
		System.out.println("JobDetail's jobClass:"+jobDetail.getJobClass().getName());
		// 创建一个Trigger实例,定义该Job立即执行,且每隔两秒钟执行一次直到永远
		Trigger trigger = TriggerBuilder.newTrigger().withIdentity("mtTrigger", "group1").startNow()
				.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();
		//创建scheduler实例
		SchedulerFactory sFactory = new StdSchedulerFactory();
		Scheduler scheduler = sFactory.getScheduler();
		scheduler.start();
		//打印当前时间
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("打印当前时间:"+sf.format(startTime));
		scheduler.scheduleJob(jobDetail,trigger);
	}
}
3.浅谈JobExecutionContext&JobDataMap

      当Schedule调用一个Job,就会将JobExecutionContext传递给Job的execute方法;Job能通过JobExecutionContext对象访问到Quartz运行时的环境以及Job本身的明细数据。在进行任务调度时,JobDataMap存储在JobExecutionContext中,非常方便获取;JobDataMap可以用来装载任何可序列化的数据对象,当job实例对象被执行时这些参数对象会传递给它;JobDataMap实现了JDK的Map接口,并且添加了一些非常方便的方法用来存取基本数据类型。获取JobDataMap的两种方式:

  • 从Map中直接获取,示例代码如下Job:
package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.TriggerKey;
public class HelloJob implements Job{
	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		//打印当前执行时间
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("任务执行时间为:"+sf.format(startTime));
		JobKey key = context.getJobDetail().getKey();
		System.out.println("My job name and group are:"+key.getName()+":"+key.getGroup());
		TriggerKey triggerKey = context.getTrigger().getKey();
		System.out.println("My trigger name and group are:"+triggerKey.getName()+":"+triggerKey.getGroup());
		JobDataMap jobMap = context.getJobDetail().getJobDataMap();
		JobDataMap triggerMap = context.getTrigger().getJobDataMap();
//		JobDataMap dataMap = context.getMergedJobDataMap(); //获取合并处理后的参数集合
		String jobMsg = jobMap.getString("message");
		Float floatValue = jobMap.getFloat("float");
		String triggerMsg = triggerMap.getString("triggerMsg");
		Double doubleValue = triggerMap.getDouble("double");
		System.out.println("My job params are:"+jobMsg+":"+floatValue);
		System.out.println("My trigger params are:"+triggerMsg+":"+doubleValue);
	}
}

示例代码Schedule:

package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
	public static void main(String[] args) throws SchedulerException {
		// 创建一个JobDetail实例与HelloJob类绑定
		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").
				usingJobData("message", "Hello MyJob1").usingJobData("float", 3.14F).build();
		
		//如果传递参数过程中key相同,则trigger的参数值会覆盖jobdetail里面的参数值
		// 创建一个Trigger实例,定义该Job立即执行,且每隔两秒钟执行一次直到永远
		Trigger trigger = TriggerBuilder.newTrigger().withIdentity("mtTrigger", "group1").
				usingJobData("triggerMsg", "Hello MyTrigger1").usingJobData("double", 2.0D).
				startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().
						withIntervalInSeconds(2).repeatForever()).build();
		//创建scheduler实例
		SchedulerFactory sFactory = new StdSchedulerFactory();
		Scheduler scheduler = sFactory.getScheduler();
		scheduler.start();
		//打印当前时间
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("打印当前时间:"+sf.format(startTime));
		scheduler.scheduleJob(jobDetail,trigger);
	}
}
  • Job实现类中添加setter方法对应JobDataMap的键值(Quartz框架默认的JobFactory实现类在初始化Job实例对象时会自动地调用这些setter方法),如下代码所示Job:
package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.TriggerKey;
public class HelloJob implements Job{
	private String message;
	private Float floatValue;
	private Double doubleValue;
	
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	public Float getFloatValue() {
		return floatValue;
	}
	public void setFloatValue(Float floatValue) {
		this.floatValue = floatValue;
	}
	public Double getDoubleValue() {
		return doubleValue;
	}
	public void setDoubleValue(Double doubleValue) {
		this.doubleValue = doubleValue;
	}
	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		//打印当前执行时间
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("任务执行时间为:"+sf.format(startTime));
		JobKey key = context.getJobDetail().getKey();
		System.out.println("My job name and group are:"+key.getName()+":"+key.getGroup());
		TriggerKey triggerKey = context.getTrigger().getKey();
		System.out.println("My trigger name and group are:"+triggerKey.getName()+":"+triggerKey.getGroup());
		System.out.println("Message is:"+message);
		System.out.println("Float is:"+floatValue);
		System.out.println("Double is:"+doubleValue);
	}
}

示例代码Schedule:

package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
	public static void main(String[] args) throws SchedulerException {
		// 创建一个JobDetail实例与HelloJob类绑定
		JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").
				usingJobData("message", "Hello MyJob1").usingJobData("floatValue", 3.14F).build();
		
		//如果传递参数过程中key相同,则trigger的参数值会覆盖jobdetail里面的参数值
		// 创建一个Trigger实例,定义该Job立即执行,且每隔两秒钟执行一次直到永远
		Trigger trigger = TriggerBuilder.newTrigger().withIdentity("mtTrigger", "group1").
				usingJobData("triggerMsg", "Hello MyTrigger1").usingJobData("doubleValue", 2.0D).
				startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().
						withIntervalInSeconds(2).repeatForever()).build();
		//创建scheduler实例
		SchedulerFactory sFactory = new StdSchedulerFactory();
		Scheduler scheduler = sFactory.getScheduler();
		scheduler.start();
		//打印当前时间
		Date startTime = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		System.out.println("打印当前时间:"+sf.format(startTime));
		scheduler.scheduleJob(jobDetail,trigger);
	}
}

猜你喜欢

转载自blog.csdn.net/u011635492/article/details/80296926