1. 程式人生 > >Quartz--任務排程的實現(例項+原始碼+驚喜)

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....
以上內容均為個人所述,如有不妥,歡迎指正,謝謝