Quartz介绍和使用
Quartz介绍和使用
什么是Quartz,干什么的?
Quartz框架是一个全功能、开源的任务调度服务,可以集成几乎任何的java应用程序—从小的单片机系统到大型的电子商务系统。Quartz可以执行上千上万的任务调度。
Quartz用来:
如网页游戏中挂机自动修炼如8个小时,人物相关数值进行成长,当使用某道具后,时间减少到4个小时,人物对应获得成长值.这其中就涉及到了Scheduler的操作,定时对人物进行更新属性操作,更改定时任务执行时间。
业务如每天凌晨2点触发数据同步、发送Email、断线等操作。
核心概念
Quartz核心的概念:scheduler任务调度、Job任务、Trigger触发器、JobDetail任务细节。
scheduler任务调度:
是最核心的概念,需要把JobDetail和Trigger注册到scheduler中,才可以执行。
// 6、工厂模式,组装各个组件<JOB,Trigger> sched.scheduleJob(job, trigger);
Job任务:
其实Job是接口,其中只有一个execute方法:
package quartz; import org.apache.log4j.Logger; import org.quartz.Job; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import java.util.Date; /** * Created by drubber on 2017/11/23. * @author drubber */ public class HelloJob implements Job { private Logger logger = Logger.getLogger(HelloJob.class); public HelloJob() { } @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDetail detail = context.getJobDetail(); String name = detail.getJobDataMap().getString("name"); logger.info("say hello to " + name + " at " + new Date()); System.out.println("---------------end----------------"); } }
我们只需要 implements 此接口,重写 execute(*) 方法。
Trigger触发器:
执行任务的规则;比如每天,每小时等。
一般情况使用SimpleTrigger,和CronTrigger,这些触发器实现了Trigger接口。或者 ScheduleBuilder 子类 SimpleScheduleBuilder和CronScheduleBuilder。
对于简单的时间来说,比如每天执行几次,使用SimpleTrigger。
对于复杂的时间表达式来说,比如每个月15日上午几点几分,使用CronTrigger以及CromExpression 类。
JobDetail:
任务细节,Quartz执行Job时,需要新建个Job实例,但是不能直接操作Job类,所以通过JobDetail来获取Job的名称、描述信息。
Quartz使用
1、导入Quartz所需的两个jar包
<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>2.2.1</version> </dependency>
2、创建我们自己的Job类实例,进行简单的输出
package quartz; import org.apache.log4j.Logger; import org.quartz.Job; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import java.util.Date; /** * Created by drubber on 2017/11/23. * @author drubber */ public class HelloJob implements Job { private Logger logger = Logger.getLogger(HelloJob.class); public HelloJob() { } @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDetail detail = context.getJobDetail(); String name = detail.getJobDataMap().getString("name"); logger.info("say hello to " + name + " at " + new Date()); System.out.println("---------------end----------------"); } }
package quartz; import org.apache.log4j.Logger; import org.junit.Before; import org.junit.Test; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerFactory; import org.quartz.Trigger; import org.quartz.impl.StdSchedulerFactory; import org.springframework.util.Log4jConfigurer; import java.io.FileNotFoundException; import java.util.Date; import static org.quartz.DateBuilder.evenMinuteDate; import static org.quartz.JobBuilder.newJob; import static org.quartz.SimpleScheduleBuilder.simpleSchedule; import static org.quartz.CronScheduleBuilder.cronSchedule; import static org.quartz.TriggerBuilder.newTrigger; /** * 此Demo将演示如何启动和关闭Quartz调度器,以及如何运作 * Created by drubber on 2017/11/23. * * @author drubber */ public class QuartzExample { private Logger log = Logger.getLogger(QuartzExample.class); public QuartzExample() { } @Before public void initLog4j(){ try { Log4jConfigurer.initLogging("classpath:config/log4j.properties"); } catch (FileNotFoundException e) { System.err.println("Cannot Initialize Log4j !!!!!!"); } } @Test public void run() throws Exception { log.info("------- Initializing ----------------------"); // 1、工厂模式 构建Scheduler的Factory\ // 2、其中StdSchedulerFactory 为Quartz默认的Factory,默认加载quartz.properties,开发者亦可自行实现自己的Factory;Job、Trigger等组件 SchedulerFactory sf = new StdSchedulerFactory(); // 2、通过SchedulerFactory获得Scheduler对象 Scheduler sched = sf.getScheduler(); log.info("------- Initializing Complete -----------------"); // 3、org.quartz.DateBuilder.evenMinuteDate <下一分钟> -- 通过DateBuilder构建Date //Date runTime = evenMinuteDate(new Date()); Date runTime = new Date(); log.info("------- Scheduling Job -------------------"); // 4、org.quartz.JobBuilder.newJob --通过JobBuilder构建Job JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").build(); //设置参数 job.getJobDataMap().put("name","drubber_ceshi"); // 5、通过TriggerBuilder进行构建 //Trigger trigger = getTrigger(runTime,"simple"); Trigger trigger = getTrigger(runTime,"cron"); // 6、工厂模式,组装各个组件<JOB,Trigger> sched.scheduleJob(job, trigger); // [group1.job1] will run at: log.info(job.getKey() + " will run at: " + runTime); //7、start sched.start(); log.info("------------Started Scheduler-----------"); Thread.sleep(10 * 1000L); log.info("-------wait 10 seconds ------"); // shut down the scheduler log.info("------- Shutting Down ---------------------"); // 8、通过Scheduler销毁内置的Trigger和Job sched.shutdown(true); log.info("------- Shutdown Complete -----------------"); } private Trigger getTrigger(Date runTime, String type) { Trigger trigger = null; if (type.equals("simple")) { //使用simpleTrigger 每秒执行一次 一直循环 只到关闭sched trigger = newTrigger().withIdentity("trigger1", "group1") .startAt(runTime) .withSchedule(simpleSchedule() .withIntervalInSeconds(1) .repeatForever()) .build(); } else if (type.equals("cron")) { //使用CronTrigger 每2秒执行一次 一直循环 只到关闭sched trigger = newTrigger().withIdentity("trigger1", "group1") .startAt(runTime) .withSchedule(cronSchedule("*/2 * * * * ? *")) .build(); }else{ //TODO } return trigger; } }
这里我们使用 SimpleTrigger 和 CronTrigger 两个值方式执行调度。 Cron Expression表达式可以查看 http://www.cnblogs.com/drubber/p/5845014.html 或者查看源码
Quartz 的调用方式
1、创建调度工厂(); //工厂模式
2、根据工厂取得调度器实例(); //工厂模式
3、Builder模式构建子组件<Job,Trigger> // builder模式, 如JobBuilder、TriggerBuilder、DateBuilder
4、通过调度器组装子组件 调度器.组装<子组件1,子组件2...> //工厂模式
5、调度器.start(); //工厂模式
lift is made up of small pleasures.
生活是由各种微小的幸福构成。
日积月累,就会产生意想不到的Miracles。
每一天的坚持,每一天的收获,我与你同在!!