轉自:https://www.cnblogs.com/wcyBlog/p/4105165.html
近日項目開發中需要執行一些定時任務,比如需要在每天早上9:00,准時發布信息,借此機會整理了一下定時任務的幾種實現方式,由於項目采用spring框架,所以我都將結合
spring框架來介紹。
一.分類
-
從實現的技術上來分類,目前主要有三種技術(或者說有三種產品):
- Java自帶的java.util.Timer類,這個類允許你調度一個java.util.TimerTask任務。使用這種方式可以讓你的程序按照某一個頻度執行,但不能在指定時間運行。一般用的較少,這篇文章將不做詳細介紹。
- 使用Quartz,這是一個功能比較強大的的調度器,可以讓你的程序在指定時間執行,也可以按照某一個頻度執行,配置起來稍顯復雜,稍后會詳細介紹。
- Spring3.0以后自帶的task,可以將它看成一個輕量級的Quartz,而且使用起來比Quartz簡單許多,稍后會介紹。
-
從作業類的繼承方式來講,可以分為兩類:
- 作業類需要繼承自特定的作業類基類,如Quartz中需要繼承自org.springframework.scheduling.quartz.QuartzJobBean;java.util.Timer中需要繼承自java.util.TimerTask。
- 作業類即普通的java類,不需要繼承自任何基類。
注:個人推薦使用第二種方式,因為這樣所以的類都是普通類,不需要事先區別對待。
-
從任務調度的觸發時機來分,這里主要是針對作業使用的觸發器,主要有以下兩種:
- 每隔指定時間則觸發一次,在Quartz中對應的觸發器為:org.springframework.scheduling.quartz.SimpleTriggerBean
- 每到指定時間則觸發一次,在Quartz中對應的調度器為:org.springframework.scheduling.quartz.CronTriggerBean
注:並非每種任務都可以使用這兩種觸發器,如java.util.TimerTask任務就只能使用第一種。Quartz和spring task都可以支持這兩種觸發條件。
二.用法
1、Java自帶的java.util.Timer類,自定義一個類繼承TimerTask
例子:
package
com.timertest;
import
java.util.Timer;
import
java.util.TimerTask;
public
class
TestTimerTask {
Timer timer;
public
TestTimerTask(
int
a) {
timer =
new
Timer();
timer.schedule(
new
GoodTimerTask(),
0
,
1000
*a);
}
public
static
void
main(String[] args) {
System.out.println(
"About to schedule task."
);
new
TestTimerTask(
3
);
}
class
GoodTimerTask
extends
TimerTask{
@Override
public
void
run() {
System.out.println(
"Timer running!"
);
}
}
}
2、Spring3.0以后自帶的task
/一、在applicationContext.xml配置的方式
//1、准備jar包
// (1)spring核心jar包
//2、在項目中寫個類
@Service
public
class
BookScheduleTask {
@Resource
private
BookService bookService;
public
Page<Book> findAllBook(){
//不帶參數
System.out.println(
"BookScheduleTask.findAllBook()"
);
return
bookService.findBook(
1
);
}
}
//3、在ApplicationContext.xml配置文件中寫如下配置:
<!-- 自動掃描 -->
<context:component-scan base-
package
=
"com"
/>
<!-- spring框架的Scheduled定時器 -->
<task:scheduled-tasks>
<task:scheduled ref=
"bookScheduleTask"
method=
"findAllBook"
cron=
"0 0 12 * * ?"
/>
</task:scheduled-tasks>
說明:(
1
)<context:component-scan base-
package
=
"com"
/>該配置,相信大家用過spring的都知道是什么意思,
是spring用於掃描注解的
(
2
)<task:scheduled-tasks>,該配置的作用是定義一個時間計划任務,定義某個類下面某個方法在某個時間執行。
<task:scheduled ref=
"bookScheduleTask"
method=
"findAllBook"
cron=
"0 0 12 * * ?"
/>,ref表示的是
某個要在規定時間執行的類,method表示要執行的類下的某個方法,cron表示時間表達式,具體詳細的表達式
可以百度查詢。
//二、基於注解的spring定時器
// 1、同上,准備好spring的jar包
// 2、在項目中創建一個類,用於執行定時任務的類。如下:
@Component
(
"bookScheduleTask"
)
public
class
BookScheduleTask {
@Resource
private
BookService bookService;
@Scheduled
(cron=
"0 50 14 * * ?"
)
public
void
findAllBook(){
System.out.println(
"BookScheduleTask.findAllBook()"
);
bookService.findBook(
1
);
}
}
// 說明:基於注解的方法,@Component("bookScheduleTask")表示定義了一個別名。
// @Scheduled(cron="0 50 14 * * ?")表示:該注解下的方法是一個時間任務,在cron="0 50 14 * * ?"(14:50)執行findAllBook()方法
3、使用quartz,重量級框架,該方式詳見
http://gong1208.iteye.com/blog/1773177