上一个项目中用到了定时任务的功能,然后我使用了Quartz,它是一个启动定时任务的框架,官网: http://www.quartz-scheduler.org ,接下来我总结下Quartz的基本用法。
建立maven 项目,导入quartz 坐标
<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>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
一:入门案例:http://www.quartz-scheduler.org/documentation/quartz-2.1.x/quick-start.html
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.StdSchedulerFactory;
public class Demo1 {
public static void main(String[] args) throws SchedulerException {
// 定时器对象
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 开启定时任务
scheduler.start();
// 关闭定时任务
scheduler.shutdown();
}
}
二:SimpleTrigger 使用
必须清楚 JobDetail 和Trigger 两个对象
Job 工作任务 ,你要做什么
Trigger 执行工作任务 触发条件 , 什么时间执行, 多久执行一次 编写工作任务
编写一个定时任务
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import cn.jack.quartz.job.HelloJob;
public class Demo2 {
public static void main(String[] args) throws SchedulerException {
// 定时器对象
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 定义一个工作对象
JobDetail job = JobBuilder.newJob(HelloJob.class)
.withIdentity("job1", "group1").build();
// 定义触发器
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1").startNow()
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))
.build();
scheduler.scheduleJob(job, trigger);
// 开启定时任务
scheduler.start();
}
}
创建一个实现Job接口的类用来执行具体的任务
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class HelloJob implements Job {
public void execute(JobExecutionContext context)
throws JobExecutionException {
System.out.println("Hello, Quartz !!!~~~~~");
}
}
对象TriggerBuilder 启动任务时间
startNow 立即启动
startAt (Date) 指定时间启动
对象 SimpleScheduleBuilder 进行简单任务重复执行
repeatSecondly …() 多少秒后重复执行
repeatminutely …() 多少分钟后重复执行
repeatHourly …() 多少小时后重复执行
三: CronTrigger 的使用
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import cn.jack.quartz.job.HelloJob;
public class Demo3 {
public static void main(String[] args) throws SchedulerException {
// 定时器对象
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 定义一个工作对象
JobDetail job = JobBuilder.newJob(HelloJob.class)
.withIdentity("job1", "group1").build();
// 定义触发器
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 0 ? * *"))
.build();
scheduler.scheduleJob(job, trigger);
// 开启定时任务
scheduler.start();
}
}
注意:day-of-month 和 day-of-week 只能设置一个值,另一个值写 ?即可,因为两者不可能同时为*
接下来是Quartz 和 Spring 集成使用
1、 建立war 包 maven 项目 quartz_spring ,导入maven 依赖
<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>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
2、 配置web.xml spring 的监听器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<!-- spring配置文件位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- spring核心监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
3、 编写Job任务程序
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import cn.jack.quartz.service.HelloService;
public class HelloJob implements Job {
@Autowired
private HelloService helloService;
public void execute(JobExecutionContext context)
throws JobExecutionException {
helloService.sayHello();
}
}
4、配置spring 的applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd ">
<context:component-scan base-package="cn.jack.quartz.service" />
<!-- job -->
<bean id="helloJob"
class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="cn.itcast.quartz.job.HelloJob" />
</bean>
<!-- trigger -->
<bean id="simpleTrigger"
class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="helloJob" />
<!-- 3秒后第一次执行 -->
<property name="startDelay" value="3000" />
<!-- 5秒后重复执行 -->
<property name="repeatInterval" value="5000" />
</bean>
<!-- scheduler -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobFactory" ref="jobFactory" />
<property name="triggers">
<list>
<ref bean="simpleTrigger"/>
</list>
</property>
</bean>
</beans>
5. Quartz 和 Spring 集成后 Bean 注入的问题解决
因为具体的Job类并没有被Spring所管理,而我们在实际业务需求中常常要调用如Service或者Dao的bean来完成具体的任务,
但在Job 中 spring 管理的Bean 无法注入,所以我们需要在Scheduler 中自定义JobFactory
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Service;
@Service("jobFactory")
public class JobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle)
throws Exception {
Object jobInstance = super.createJobInstance(bundle);
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
然后配置applicationContext.xml,为scheduler设置jobFactory
<!-- scheduler -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobFactory" ref="jobFactory" />
<property name="triggers">
<list>
<ref bean="simpleTrigger"/>
</list>
</property>
</bean>
自此,Spring对Quartz的集成就写完了。