从 技术上说实现定时任务常见的方法有三种
- Java自带的java.util.Timer类
- 使用Quartz调度器,这种方式需要第三方jar支持
- Spring3.0以后自带的task定时器
第一种方式在这里就不多做说明了,因为timer类功能比较单一,在实际项目中运用也比较少
Quartz
Quartz的使用方式大致有三种,这三种方式的在这里都会和Spring进行整合所以都会用到applicationContext.xml进行配置
- 实现org.quartz.StatefulJob或org.quartz.Job接口
- 继承org.springframework.scheduling.quartz.QuartzJobBean类
- 普通类+xml配置文件
1.实现org.quartz.StatefulJob或org.quartz.Job接口首先在applicationContext.xml配置定时任务tomcat加载的初始化类,加载时运行init方法
<!-- 实现定时任务接口启动类 --> | |
<bean id="StarJob" class="com.lovo.task.server.impl.StarJob" init-method="init"></bean> |
初始化类代码
package com.lovo.task.server.impl; | |
import org.quartz.Scheduler; | |
import org.quartz.SchedulerException; | |
import org.quartz.SchedulerFactory; | |
import org.quartz.impl.StdSchedulerFactory; | |
public class StarJob { | |
public void init() throws SchedulerException{ | |
//TestImpl为定时任务的配置实现类 | |
TestImpl impl=new TestImpl(); | |
SchedulerFactory factory = new StdSchedulerFactory(); | |
Scheduler scheduler = factory.getScheduler(); | |
try { | |
//触发作业类及触发器方法 | |
impl.startJob(scheduler); | |
} catch (Throwable e) { | |
// TODO Auto-generated catch block | |
e.printStackTrace(); | |
} | |
//启动定时任务 | |
scheduler.start(); | |
} | |
} |
作业及调度实现类
package com.lovo.task.server.impl; | |
import java.text.ParseException; | |
import org.quartz.CronTrigger; | |
import org.quartz.JobDetail; | |
import org.quartz.JobExecutionContext; | |
import org.quartz.JobExecutionException; | |
import org.quartz.Scheduler; | |
import org.quartz.SchedulerException; | |
import org.quartz.SchedulerFactory; | |
import org.quartz.StatefulJob; | |
import org.quartz.Trigger; | |
import org.quartz.TriggerUtils; | |
import org.quartz.impl.StdSchedulerFactory; | |
import com.lovo.task.server.ITest; | |
public class TestImpl implements StatefulJob,ITest { | |
public void execute(JobExecutionContext arg0) throws JobExecutionException { | |
// TODO Auto-generated method stub | |
test(); | |
} | |
public void startJob(Scheduler scheduler) throws Throwable { | |
//配置作业类 | |
JobDetail JobDetail=new JobDetail("TestImpl",Scheduler.DEFAULT_GROUP, TestImpl.class); | |
//任意每分钟类从0开始55结束,每5秒执行一次 | |
String rex="0/5 * * * * ?"; | |
//触发器,配置调度工厂 | |
CronTrigger trigger=new CronTrigger("testTrigger","testGroup", rex); | |
scheduler.scheduleJob(JobDetail, trigger); | |
//固定每10秒执行一次 | |
// Trigger simplerTrigger = TriggerUtils.makeSecondlyTrigger(10); | |
// simplerTrigger.setName("SimpleTrigger"); | |
// scheduler.scheduleJob(JobDetail, simplerTrigger); | |
} | |
public void test(){ | |
System.out.println("测试"); | |
} | |
} |
2.继承org.springframework.scheduling.quartz.QuartzJobBean类
首先在xml中进行配置
<!-- 配置计时任务 --> | |
<!-- 配置作业bean --> | |
<bean id="TestTaskImpl" class="org.springframework.scheduling.quartz.JobDetailBean"> | |
<!-- value为类路径 --> | |
<property name="jobClass" value="com.lovo.task.server.impl.TestTaskImpl"></property> | |
<!-- 此属性定义方法需注入的属性值,time为工厂调度后多久开始执行 --> | |
<property name="jobDataAsMap"> | |
<map> | |
<entry key="timeout" value="0"></entry> | |
</map> | |
</property> | |
</bean> | |
<!-- 配置调度触发器 触发器有两种配置方式,一直是固定多少时间循环一次,一种是每天固定几点执行一次,--> | |
<!-- 固定频率执行 --> | |
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> | |
<property name="jobDetail" ref="TestTaskImpl"></property> | |
<!-- 实例化后多久开始执行 --> | |
<property name="startDelay" value="0"></property> | |
<!-- 间隔频率,单位毫秒 --> | |
<property name="repeatInterval" value="1000"></property> | |
</bean> | |
<!-- 固定时间 每天12:00运行一次--> | |
<!-- <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> | |
<property name="jobDetail" ref="TestTaskImpl" /> | |
<property name="cronExpression" value="0 0 12 * * ?" /> | |
</bean> --> | |
<!-- 配置调度工厂 --> | |
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> | |
<property name="triggers"> | |
<list> | |
<ref bean="simpleTrigger" /> | |
</list> | |
</property> | |
</bean> |
作业类代码
package com.lovo.task.server.impl; | |
import org.quartz.JobExecutionContext; | |
import org.quartz.JobExecutionException; | |
import org.springframework.scheduling.quartz.QuartzJobBean; | |
import com.lovo.task.server.TestTask; | |
public class TestTaskImpl extends QuartzJobBean implements TestTask{ | |
//time为工厂调度后多久开始执行 | |
private int timeout; | |
public static int INDEX; | |
public void setTime(int timeout) { | |
this.timeout = timeout; | |
} | |
protected void executeInternal(JobExecutionContext arg0) | |
throws JobExecutionException { | |
// TODO Auto-generated method stub | |
testTask(); | |
} | |
public void testTask() { | |
// TODO Auto-generated method stub | |
INDEX++; | |
System.out.println("执行计时任务第"+INDEX+"次"); | |
} | |
} |
3.普通类+xml配置文件
首先定义个普通JAVA类
package com.lovo.task.server; | |
public class TestTask02 { | |
public void Task(){ | |
System.out.println("普通类实现定时任务"); | |
} | |
} |
在xml中进行配置
<!-- 普通类实现定时任务 --> | |
<!-- 配置作业类 --> | |
<bean id="Task02" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> | |
<!-- targetObject指定任务类 --> | |
<property name="targetObject"> | |
<bean class="com.lovo.task.server.TestTask02"></bean> | |
</property> | |
<!-- targetMethod指定运行的方法 --> | |
<property name="targetMethod" value="Task"></property> | |
<!-- 不并发调度 --> | |
<property name="concurrent" value="false"></property> | |
</bean> | |
<!-- 配置调度触发器 触发器有两种配置方式,一直是固定多少时间循环一次,一种是每天固定几点执行一次 --> | |
<bean id="simpleTrigger02" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> | |
<property name="jobDetail" ref="Task02"></property> | |
<!-- 实例化后多久开始执行 --> | |
<property name="startDelay" value="0"></property> | |
<!-- 间隔频率,单位毫秒 --> | |
<property name="repeatInterval" value="1000"></property> | |
</bean> | |
<!-- 固定时间 每天12:00运行一次--> | |
<!-- <bean id="cronTrigger02" class="org.springframework.scheduling.quartz.CronTriggerBean"> | |
<property name="jobDetail" ref="Task02" /> | |
<property name="cronExpression" value="0 0 12 * * ?" /> | |
</bean> --> | |
<!-- 配置调度工厂 --> | |
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> | |
<property name="triggers"> | |
<list> | |
<ref bean="simpleTrigger02" /> | |
</list> | |
</property> | |
</bean> |
Spring-Task
Spring自带的Task实现定时任务也有两种方式,一种是xml配置的方式,一种是使用注解@Scheduled,不管是那种方式,首先都需要在xml开头声明task
<beans xmlns="#34; | |
xmlns:xsi="#34; xmlns:p="#34; | |
xmlns:context="#34; | |
xmlns:aop="#34; xmlns:tx="#34; | |
xmlns:task="#34; | |
xsi:schemaLocation=" | |
#34;> |
配置定时器开关
<!-- 配置定时器开关 里面可以配置很多参数,这里只是简单的打开task,并支持@Scheduled --> | |
<!-- 配置定时器注解开关 里面可以配置很多参数,这里只是简单的打开task,并支持@Scheduled --> | |
<task:scheduler id="Scheduler" pool-size="10"/> | |
<task:annotation-driven scheduler="Scheduler" proxy-target-class="true"/> |
基于注解的任务类
package com.lovo.task.server; | |
import org.springframework.scheduling.annotation.Scheduled; | |
import org.springframework.stereotype.Component; | |
public class Task03 { | |
public void test(){ | |
System.out.println("task定时任务"); | |
} | |
} |
如果不习惯注解的,追求代码的简洁性,也可以在xml中配置task定时任务
<!-- 配置作业bean --> | |
<bean id="xmlTask" class="com.lovo.task.server.Task04"></bean> | |
<!-- 配置执行规则 method为作业方法--> | |
<task:scheduled-tasks> | |
<task:scheduled ref="xmlTask" method="test" cron="0/2 * * * * ?"/> | |
</task:scheduled-tasks> | |
<!-- 配置定时器注解开关 里面可以配置很多参数,这里只是简单的打开task,并支持@Scheduled --> | |
<task:scheduler id="Scheduler" pool-size="10"/> | |
<task:annotation-driven scheduler="Scheduler" proxy-target-class="true"/> |
定时任务
package com.lovo.task.server; | |
public class Task04 { | |
public void test(){ | |
System.out.println("xml中配置Task"); | |
} | |
} |
参考来源:
cronExpression语法 | |
字段 允许值 允许的特殊字符 | |
秒 0-59 , - * / | |
分 0-59 , - * / | |
小时 0-23 , - * / | |
日期 1-31 , - * ? / L W C | |
月份 1-12 或者 JAN-DEC , - * / | |
星期 1-7 或者 SUN-SAT , - * ? / L C # | |
年(可选) 留空, 1970-2099 , - * / | |
区间 | |
通配符 | |
? 你不想设置那个字段 | |
下面只例出几个式子 | |
CRON表达式 含义 | |
"0 0 12 * * ?" 每天中午十二点触发 | |
"0 15 10 ? * *" 每天早上10:15触发 | |
"0 15 10 * * ?" 每天早上10:15触发 | |
"0 15 10 * * ? *" 每天早上10:15触发 | |
"0 15 10 * * ? 2005" 2005年的每天早上10:15触发 | |
"0 * 14 * * ?" 每天从下午2点开始到2点59分每分钟一次触发 | |
"0 0/5 14 * * ?" 每天从下午2点开始到2:55分结束每5分钟一次触发 | |
"0 0/5 14,18 * * ?" 每天的下午2点至2:55和6点至6点55分两个时间段内每5分钟一次触发 | |
"0 0-5 14 * * ?" 每天14:00至14:05每分钟一次触发 | |
"0 10,44 14 ? 3 WED" 三月的每周三的14:10和14:44触发 | |
"0 15 10 ? * MON-FRI" 每个周一、周二、周三、周四、周五的10:15触发 |