任务调度
在企业级应用中,经常会制定一些“计划任务”,即在某个时间点做某件事情 核心是以时间为关注点,即在一个特定的时间点,系统执行指定的一个操作 任务调度涉及多线程并发、线程池维护、运行时间规则解析、运行现场的保护以恢复等方面 Quartz框架是一个开源的企业级任务调度服务,已经被作为任务调度的良好解决方案.
Quartz框架核心
Quartz对任务调度进行了高度抽象,提出了3个核心概念,并在org.quartz包中通过接口和类进行了描述 任务:就是执行的工作内容。Quartz提供Job接口来支持任务定义 触发器:定义触发Job执行的时间触发规则。Quartz提供Trigger类及其子类支持触发器功能, 调度器:Quartz提供了Scheduler接口,将工作任务和触发器绑定,保证任务可以在正确的时间执行
运行环境
任务调度
任务执行
任务持久化
事务
集群
监听器和插进
下面我们直接来看例子
我们创建一个计划类 Plan
开始创建entity实体层定义任务的模板
public class Plan { private String date;//时间 private String task;//任务 /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return "Plan [date=" + date + ", task=" + task + "]"; } public Plan() { super(); // TODO Auto-generated constructor stub } public Plan(String date, String task) { super(); this.date = date; this.task = task; }
我们创建一个提醒服务类RemindService
定制一个泛型集合用户存储多个Plan对象,提供一个方法读取该泛型集合中的data
*/ public class RemindService { public void printPlan(String userName){ List<Plan> plansFormToday=getPlansFormToday(userName); System.out.println(userName+"//"); for (Plan plan : plansFormToday) { System.out.println(plan+"\\\\"); } } private List<Plan> getPlansFormToday(String userName) { //模拟数据库查询,仅说明问题 List<Plan> list=new ArrayList<Plan>(); list.add(new Plan("2016-11-3 14:31:11","陶研会|地点:会议室C01")); list.add(new Plan("2016-11-3 14:31:20","总裁办公室|地点:总裁办公室")); return list; }
我们创建一个任务调度类RemindJob
/** * 提醒业务类 * @author Admin * */ public class RemindJob implements Job { private RemindService service=new RemindService(); @Override public void execute(JobExecutionContext context) throws JobExecutionException { service.printPlan("你好!"); } /** * @return the service */ public RemindService getService() { return service; } /** * @param service the service to set */ public void setService(RemindService service) { this.service = service; }
核心代码解析:
Job接口中只有一个 execute()方法,在实现类中 实现该方法以执行具体任务。
通过参数 JobExecutionContext 可以获取调度上下文的各 种信息,如:任务名称等
在原RemindJob的execute()方法中添加以下代码,可以获取该任务的名称、 绑定的触发器的名称和每次任务触发时间
//获取用户信息 JobDataMap dataMap = context.getJobDetail().getJobDataMap(); String value = (String)dataMap.get("happykey"); System.out.println(value); System.out.println("TriggerName\t"+context.getTrigger().getKey().getName()); System.out.println("JobName\t"+context.getJobDetail().getKey().getName());
真正的任务对象和触发器对象 Test
public class Test { public static void main(String[] args) throws SchedulerException { doRemind(); } public static void doRemind() throws SchedulerException{ JobDetail job = JobBuilder.newJob(RemindJob.class) .withIdentity("job1", "group1").build();//创建一个任务 /** * 创建触发器 * 第一种方式 不太好 */ /*SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "myTriggerGroup"). withSchedule(SimpleScheduleBuilder.simpleSchedule(). withIntervalInSeconds(3). repeatForever()). startAt(new Date(System.currentTimeMillis()+1000)).build();*/ /** * 创建触发器 * 第二种 方式 非常好 * 可以 好用 2013年每月的第三个星期五上午10:30触发 0 30 10 ? * 6#3 2013 * 2016年每月的第一个星期四下午16:17触发 0 17 16 ? * 5#1 2016 * 每天15点到16点每5分钟运行一次,此外,每天17点到18点每5分钟运行一次 */ CronTrigger trigger=TriggerBuilder.newTrigger() .withIdentity("myTrigger", "myTriggerGroup") .withSchedule(CronScheduleBuilder.cronSchedule("0 18 16 ? * 5#1 2016")).build(); SchedulerFactory sf=new StdSchedulerFactory();//创建调度者工厂 Scheduler scheduler = sf.getScheduler();//创建一个调度者 scheduler.scheduleJob(job,trigger);//注册并进行调度 scheduler.start();//启动调度 //Thread.sleep(millis) //scheduler.shutdown();//关闭调度 }
核心代码解析:
这是通过JobDetail创建一个任务实例。
还可以通过JobDetail的JobDataMap对象来进行初始数据的设置,如传入需要提醒的用户姓名
public class TestJob { public void doRemind() throws SchedulerException, InterruptedException { JobDetail job = new JobDetail("remindJob", "group1", RemindJob.class); // 获取和任务关联的JobDataMap对象 JobDataMap dataMap = job.getJobDataMap(); dataMap.put("user", "张三"); // 在JobDataMap对象中设置用户数据 // 省略原有程序代码 } }
JobBuilder类
使用SimpleTrigger创建一个触发器
SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "myTriggerGroup"). withSchedule(SimpleScheduleBuilder.simpleSchedule(). withIntervalInSeconds(). repeatForever()). startAt()).build();
创建一个调度器
SchedulerFactory sf=new StdSchedulerFactory();//创建调度者工厂 Scheduler scheduler = sf.getScheduler();//创建一个调度者
注册任务和触发器
scheduler.scheduleJob(job,trigger);//注册并进行调度 scheduler.start();//启动调度
启动和关闭调度
sched.start(); sched.shutdown();
上面的例子,基本算是完成了任务调度。
期待 第二版