参考文章:https://blog.csdn.net/chen3749102/article/details/53431470
https://blog.csdn.net/shasiqq/article/details/51023762
http://www.cnblogs.com/drift-ice/p/3817269.html
一、quartz是现在常用的定时任务框架之一。
二、代码入门:采用常见的 spring-maven架构。
2.1 pom.xml添加:
<!-- quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
2.2 spring的applicationContext.xml的配置信息里面加上如下定义的代码:
<!-- 工作的bean -->
<bean id="myJob" class="com.haoxin.web.ops.ad.util.QuartzJob" />
<!-- job的配置开始 -->
<bean id="myJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="myJob" />
</property>
<property name="targetMethod">
<value>work</value>
</property>
</bean>
<!-- job的配置结束 -->
<!-- 调度的配置开始 -->
<bean id="crontestJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail">
<ref bean="myJobDetail" />
</property>
<property name="cronExpression">
<value>10 0/1 * * * ?</value> <!-- Cron表达式“10 */1 * * * ?”意为:从10秒开始,每1分钟执行一次。 -->
</property>
</bean>
<!-- 调度的配置结束 -->
<!-- 启动触发器的配置开始 -->
<bean name="startQuertz" lazy-init="false" autowire="no"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="crontestJobTrigger" />
</list>
</property>
</bean>
<!-- 启动触发器的配置结束 -->
至此,环境就搭好了。
2.3 定义一个Quartz的实现类,要实现Job接口或StatefulJob接口,并覆写execute方法:
package com.luo.quartzTest;
import java.util.Date;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.StatefulJob;
public class HelloQuartz implements StatefulJob {
public HelloQuartz() {
}
public void execute(JobExecutionContext context) throws JobExecutionException {
JobDetail detail = context.getJobDetail();
String name = detail.getJobDataMap().getString("name");
System.out.println("say hello to " + name + " at " + new Date());
}
}
2.4 写一个job定时任务的测试类,其实这个类里的代码可以写在上面定义的那个类里面,这里为了方便代码复用,另写一个。
package com.luo.quartzTest;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
import static org.quartz.DateBuilder.newDate ;
import static org.quartz.JobBuilder.newJob ;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule ;
import static org.quartz.TriggerBuilder.newTrigger ;
public class QuartzTest {
public QuartzTest() {
// TODO 自动生成的构造函数存根
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
try {
//创建scheduler
Scheduler scheduler = StdSchedulerFactory . getDefaultScheduler ();
//定义一个Trigger
Trigger trigger = newTrigger().withIdentity( "trigger1" , "group1" )
.startNow() //一旦加入scheduler,立即生效
.withSchedule(simpleSchedule() //使用SimpleTrigger
.withIntervalInSeconds(1)//每隔一秒执行一次
.repeatForever()) //一直执行,奔腾到老不停歇
.build();
//定义一个JobDetail
JobDetail job = newJob(HelloQuartz.class) //定义Job类为HelloQuartz类,这是真正的执行逻辑所在
.withIdentity( "job1" , "group1" ) //定义name/group
.usingJobData( "name" , "quartz" ) //定义属性
.build();
//加入这个调度
scheduler.scheduleJob(job,trigger);
//启动之
scheduler.start();
//运行一段时间后关闭
Thread.sleep(10000);
scheduler.shutdown(true);
}catch(Exception e) {
e.printStackTrace();
}
}
}
至此,代码结束。在该测试类里面启动main方法,eclipse后天就可以看到定时任务的执行效果。
三、说明。
3.1 Quartz框架主要的API接口主要有下面几个:
1) scheduler- 调度器的主接口
2) Job -- 一个Java类想要成为一个Job必须实现这个类
3) JobDetail -- 用来定义Job实例
4) Trigger -- 触发器实例
5)JobBuilder -- 用来定义JobDetail实例
6)TriggerBuilder -- 用来定义触发器实例
3.2 一个scheduler的生命周期从它被schedulerFactory创u开始被shutdown结束。一旦一个scheduler被创建以后,我们就可以向这个调度器添加、删除Job和Trigger,列出这个scheduler绑定的Job和Trigger,以及其他操作(比如将某个Trigger挂起)。如果scheduler的start方法不被调用,绑定到他上面的Trigger和Job都不会生效。
3.3 Quartz框架提供了一些“Builder”类,下面我们代码我们在上一节中见过,这里我们再拿出来做下示范:
// define the job and tie it to our HelloJob class
JobDetail job = newJob(HelloJob.class)
.withIdentity("myJob", "group1") // name "myJob", group "group1"
.build();
// Trigger the job to run now, and then every 40 seconds
Trigger trigger = newTrigger()
.withIdentity("myTrigger", "group1")
.startNow()
.withSchedule(simpleSchedule()
.withIntervalInSeconds(40)
.repeatForever())
.build();
// Tell quartz to schedule the job using our trigger
sched.scheduleJob(job, trigger);
上面的代码通过从JobBuilder静态导入的方法创建一个Job,同样的,通过从TriggerBuilder导入的静态方法创建Trigger。
3.4 Quartz框架提供了多种scheduleBuilder类,这些类可以创建不同类型的scheduler。DateBuilder类提供了很多方法能够很方便的构建特定时间点的时间实例(比如说能够得到当前时间的下个整点时间点 )。
3.5
当一个Job的触发器触发的时候,上面的execute方法会被调用。JobExecutionContext包含了Job的运行时信息 。
JobDetail对象是在被添加到调度器的时候被Quartz客户端(也就是你的程序)创建的。JobDetail这个对象有很多属性可以设置,比如说JobDataMap,它可以被用来存储一个 Job的状态信息。JobDataMap是我们定义一个Job时最重要的东西,在后面的章节中我们会重点讨论。
触发器对象用来触发一个Job的执行。当你想要调度一个Job的时候,你需要实例化一个触发器并将它的触发时间调整到你希望的时间点。触发器也可以有和他们关联的JobDataMap(当多个触发器会触发同一个Job,但是需要向这个Job传递不同的data时特别有用)。Quartz框架有很多种触发器,最常用的是SimpleTrigger和CronTrigg。
3.6 Job和触发器分开设计,有很多好处。比如,Job可以独立于Trigger之外存储在scheduler中,多个触发器可以被绑定到一个Job。这种松耦合的另外一种好处是:当一个Trigger过期之后,可以重新复用和这个Trigger绑定的Job。