Quartz--任務排程的實現(例項+原始碼+驚喜)
首先,說一下什麼叫做任務排程 詢問度娘中....
看了一下,度娘說的還挺囉嗦的,實在不懂的可以去問問度娘,在這我就不貼上了。
就我的話來說,任務排程,就是在一個合適的時機去執行一項任務,當然這個時機是有計劃的。例如,你定了一個鬧鐘,到了指定的時間鬧鐘就會響,這就是一個任務的排程,包括指定的時機(鬧鐘定的時間),任務的進行及完成(鬧鐘響,你起床)。當然,這只是其中的一種理解....好了廢話不多說,進入正題:
Quartz是一個完全由java編寫的開源作業排程框架。不要讓作業排程這個術語嚇著你。儘管Quartz框架整合了許多額外功能, 但就其簡易形式看,你會發現它易用得簡直讓人受不了!(這是度孃的說法)
不過,看了這篇文章之後,你也會覺得它足夠簡單
說道Quartz,不得不提到它的兩個物件:
Job : 工作任務,你要做什麼
Trigger :執行工作任務觸發條件,什麼時間執行,多久執行一次
在你的Job介面實現類裡面,新增一些邏輯到execute()方法。一旦你配置好Job實現類並設定好排程時間表,Quartz將密切注意剩餘時間。當排程程式確定該是通知你的作業的時候,Quartz框架將呼叫你Job實現類(作業類)上的execute()方法並允許做它該做的事情。無需報告任何東西給排程器或呼叫任何特定的東西。僅僅執行任務和結束任務即可。如果配置你的作業在隨後再次被呼叫,Quartz框架將在恰當的時間再次呼叫它。
在實際開發中的應用(舉個栗子):
1.商城的促銷活動,當你設定一個商品限時打折之後,務必會在活動結束之後將商品恢復原價,這就需要設定一個Trigger(在活動結束時執行一個任務,即Job),還需要設定一個Job(執行的事情就是將商品恢復原價)。
2.再比如,QQ上,到了你的生日或者你好友的生日,都會給你發出提醒,這使用了任務排程。
知道了要做什麼事,接下來就開懟吧:
在這裡,我給出的例子是ssm框架+Quartz任務排程的一個簡單實現,撇開ssm不說(有沒有,都不影響你的練習),Quartz的程式碼大概就是以下內容(也不能說是大概內容,可以說是全部內容吧,不要問我為什麼,度娘說了:“你會發現它易用得簡直讓人受不了”):
圖中一共提到了兩種配置任務排程的方法(圖中已經介紹的很詳細了),這麼看著不方便的話,你可以把圖片下載下來,一邊理解一邊看,順著線條找到思路。
下面是程式碼:
Quartz需要的依賴:
<!-- 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>
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="com.cc" />
<!-- 第一種 建立重複定時任務 迴圈的時間段 -->
<bean id="updateHotMovie" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.cc.job.UpdateHotMovie" />
</bean>
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="updateHotMovie" /> <!-- 工作細節 -->
<property name="startDelay" value="0" /> <!-- 啟動延遲 -->
<property name="repeatInterval" value="10000" /> <!-- 重複間隔 -->
</bean>
<!-- 固定 -->
<!-- <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobFactory" ref="jobFactory" />
<property name="triggers">
<list>
<ref bean="simpleTrigger"/>
</list>
</property>
</bean> -->
<!--===========================================================-->
<!-- 第二種 : 使用cron表示式配置時間 可以是時間段,也可以是時間點-->
<bean id="delUglyMovie" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.cc.job.DelUglyMovie"/>
<!--工作資料地圖-->
<property name="jobDataAsMap">
<map>
<!--超時時間-->
<entry key="timeout" value="5"/>
</map>
</property>
</bean>
<!-- 排程觸發器 -->
<bean id="cronTriggerBean" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="delUglyMovie"></property>
<property name="cronExpression" value="0 0,2 * * * ? "></property> <!-- cron表示式,設定時間 http://cron.qqe2.com/-->
</bean>
<!-- 排程工廠 固定-->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobFactory" ref="jobFactory" /> <!-- 自定義的jobFactory為了防止注入失敗的問題 -->
<property name="triggers">
<list>
<ref bean="simpleTrigger"/>
<ref bean="cronTriggerBean" />
</list>
</property>
</bean>
</beans>
自定義的工廠類 JobFactory :
package com.cc.job;
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;
}
}
任務類 DelUglyMovie :
package com.cc.job;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Service;
/**
* @author peng 2018年4月2日
* 刪除難看的
*/
@Service
public class DelUglyMovie implements Job{
/* (non-javadoc)
* @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
*/
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
System.out.println("執行DelUglyMovie");
System.out.println(new Date());
}
}
任務類 UpdateHotMovie :
package com.cc.job;
import java.util.List;
import javax.annotation.Resource;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Service;
import com.cc.domain.Movie;
import com.cc.service.MovieService;
/**
* @author peng 2018年4月2日
*
*/
@Service
public class UpdateHotMovie implements Job{
@Resource
private MovieService movieService;
/* (non-javadoc)
* @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
*/
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
System.out.println("執行定時任務");
List<Movie> movies = movieService.findAll();
for (Movie movie : movies) {
System.out.println(movie);
}
}
}
順便告訴你個事,文中也提到了一個叫做cron表示式的東東,它是什麼,你可以百度一下,然後你會發現,知道是什麼了之後不會寫怎麼辦,我會告訴你,莫慌,看法寶: http://cron.qqe2.com,這是一個自動生成cron表示式的地方,怎麼操作,看了就知道了,一般人我不告訴他....
java就像一盒巧克力,你永遠不知道,ta還爆出什麼bug....
以上內容均為個人所述,如有不妥,歡迎指正,謝謝