定时任务是开发中不可避免的,一直稀里糊涂的使用,今天结合网上的资料做个总结。
一.
定时器
分类
JDK自带的
java.util.Timer
类(固定频率,用的较少)。
Quartz
(固定频率/周期都可以,用的多,基于xml配置,较繁琐)
Spring3.0以后自带的
task
(固定频率/周期都可以,用的多,基于xml配置注解都可以,推荐)。
二.Quartz和spring task
1.Quartz
a.继承自特定的基类:org.springframework.scheduling.quartz.QuartzJobBean。
第一步:定义作业类
Java代码
public
class
Job
extends
QuartzJobBean {
private
int
timeout;
private
static
int
i =
0
;
//调度工厂实例化后,经过timeout时间开始执行调度
public
void
setTimeout(
int
timeout) {
this
.timeout = timeout;
}
@Override
protected
void
executeInternal(JobExecutionContext context)
throws
JobExecutionException {
System.out.println(
"执行具体任务…"
);
}
}
第二步:配置作业类(JobDetailBean)
Xml代码
<bean
name
=
"job"
class
=
"org.springframework.scheduling.quartz.JobDetailBean"
>
<property
name
=
"jobClass"
value
="
xxx.xxx.Job"
/>
<property
name
=
"jobDataAsMap"
>
<map>
<entry
key
=
"timeout"
value
=
"0"
/>
</map>
</property>
</bean>
说明:org.springframework.scheduling.quartz.JobDetailBean有两个属性,jobClass属性即我们在java代码中定义的任务类,jobDataAsMap属性即该任务类中需要注入的属性值。
第三步:配置作业调度的触发方式(触发器)
Xml代码
<bean
id
=
"simpleTrigger"
class
=
"org.springframework.scheduling.quartz.SimpleTriggerBean"
>
<property
name
=
"jobDetail"
ref
=
"job"
/>
<property
name
=
"startDelay"
value
=
"0"
/>
<!-- 调度工厂实例化后,经过0秒开始执行调度 ->
<property
name
=
"repeatInterval"
value
=
"2000"
/>
<!-- 每2秒调度一次 -->
</bean>
或者
<bean
id
=
"cronTrigger"
class
=
"org.springframework.scheduling.quartz.CronTriggerBean"
>
<property
name
=
"jobDetail"
ref
=
"job"
/>
<!—每天12:00运行一次 --
>
<property
name
=
"cronExpression"
value
=
"0 0 12 * * ?"
/>
</bean>
第四步:配置调度工厂
Xml代码
<bean
class
=
"org.springframework.scheduling.quartz.SchedulerFactoryBean"
>
<property
name
=
"triggers"
>
<list>
<ref
bean
=
"cronTrigger"
/>
</list>
</property>
</bean>
b.作业类不继承特定基类。
Spring能够支持这种方式,归功于两个类:
org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean(针对JDK自带的Timer,用的少)
org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean(quartz,经常使用)
第一步:编写任务类(普通的pojo)
Java代码
public
class
Job {
public
void
doJob() {
System.out.println(
"不继承QuartzJobBean方式-调度进行中..."
);
}
}
第二步:配置作业类
Xml代码
<bean
id
=
"job2"
class
=
"org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
>
<property
name
=
"targetObject"
>
<bean
class
=
"xxx.xxx.Job"
/>
</property>
<property
name
=
"targetMethod"
value
=
"doJob"
/>
<property
name
=
"concurrent"
value
=
"false"
/>
<!-- 作业不并发调度 -->
</bean>
第三步:配置作业调度的触发方式(触发器)
Xml代码
<bean
id
=
"simpleTrigger"
class
=
"org.springframework.scheduling.quartz.SimpleTriggerBean"
>
<property
name
=
"jobDetail"
ref
=
"job"
/>
<property
name
=
"startDelay"
value
=
"0"
/>
<!-- 调度工厂实例化后,经过0秒开始执行调度 -->
<property
name
=
"repeatInterval"
value
=
"5000"
/>
<!-- 每5秒调度一次 -->
</bean>
或者
<bean
id
=
"cronTrigger"
class
=
"org.springframework.scheduling.quartz.CronTriggerBean"
>
<property
name
=
"jobDetail"
ref
=
"job"
/>
<!—每天凌晨1点运行一次 --
>
<property
name
=
"cronExpression"
value
=
"0 0 01 * * ?"
/>
- </bean>
以上两种调度方式根据实际情况,任选一种即可。
第四步:配置调度工厂
Xml代码
<bean
class
=
"org.springframework.scheduling.quartz.SchedulerFactoryBean"
>
<property
name
=
"triggers"
>
<list>
<ref
bean
=
"cronTrigger"
/>
</list>
</property>
</bean>
2.Spring-Task
a.配置文件方式
第一步:编写作业类
即普通的pojo,如下:
Java代码
@Service
public
class
TaskJob {
public
void
job1() {
System.out.println(“任务进行中。。。”);
}
}
第二步:在spring配置文件头中添加命名空间及描述
Xml代码
<beans
xmlns
=
"http://www.springframework.org/schema/beans"
xmlns:task
=
"http://www.springframework.org/schema/task"
。。。。。。
xsi:schemaLocation
=
"http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task3.0.xsd"
>
第三步:spring配置文件中设置具体的任务
Xml代码
<task:scheduled-tasks>
<task:scheduled
ref
=
"taskJob"
method
=
"job"
cron
=
"0 * * * * ?"
/>
</task:scheduled-tasks>
<context:component-scan
base-package
=
" xxx.xxx.mytask "
/>
b.使用注解形式
Java代码
@Target
({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.ANNOTATION_TYPE})
@Retention
(RetentionPolicy.RUNTIME)
@Documented
public
@interface
Scheduled
{
public
abstract
String cron();//
cron表达式
public
abstract
long
fixedDelay();//
上一个任务完成开始到下一个任务开始的间隔
(ms)
public
abstract
long
fixedRate(); //
上一个任务开始到下一个任务开始的间
(ms
}
第一步:编写pojo
Java代码
@Component
(“taskJob”)
public
class
TaskJob {
@Scheduled
(cron =
"0 0 3 * * ?"
)
public
void
job1() {
System.out.println(“任务进行中。。。”);
}
}
第二步:task配置:
Xml代码
<context:annotation-config
/>
<!—spring扫描注解的配置 --
>
<context:component-scan
base-package
=
"xxx.xxx.mytask"
/>
<!—开启这个配置,spring才能识别@Scheduled注解 --
>
<task:annotation-driven/>
几个cronExpression例子
"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触发