調度器(Quartz)

任務調度的時機(背景)

        例如在開發購物網站時會遇到一個問題,因白天訂單多流量大,爲減輕網站壓力要求一些不是太急的任務(如給註冊用戶發送廣告郵件、清理平常垃圾信息等)放在凌晨流量較小時間段去執行,這個時候就須要使用到任務調度,指定在某個時間內執行某個任務java

任務調度實現方式

  • 藉助java.util.Timer來實現的。對於更加複雜任務調度,Timer不太容易(定時器)
  • 使用Spring的Quartz調度器可彌補Timer的不足,使開發者能完成各類複雜任務調度(調度器)

spring調度器(Quartz)

介紹

        Quartz調度器爲調度工做提供更豐富的支持,與Java定時器同樣,可以使用Quartz指定每隔多少毫秒執行一個工做,但Quartz比Java的Timer優點在於Quartz容許調度一個工做在某個特定的時間或日期執行。web

使用Quartz有兩種方式實現

  • 任務類繼承QuartzJobBean
  • 在配置文件中定義任務類和要執行的方法(藉助:MethodInvokingJobDetailFactoryBean)

Spring實現調度器基本步驟

第一步:建立一個用於指定執行任務的QuartzJobBean子類

        QuartzJobBean實現org.quartz.Job接口。QuartzJobBean子類應當覆蓋executeInternal()方法,在executeInternal()方法中定義預約的時刻應執行動做(這一步是指明作什麼)spring

參考代碼以下:CustomerQuartzJobBean.javaapp

package www.enfp.cc.springquartz;

import java.util.Date;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class CustomerQuartzJobBean extends QuartzJobBean
{

	@Override
	protected void executeInternal(JobExecutionContext arg0)
			throws JobExecutionException
	{
		//指定須要執行的任務,這裏僅僅是輸出當前時間
		System.out.println("執行調度任務: (當前時間:" + new Date() + ")");
	}
}

第二步:在配置文件中進行調度器的相關配置(beans.xml)

1.配置執行工做<作什麼>ide

        JobDetailBean是Quartz的JobDetail的子類,經過jobClass屬性來設置一個Job對象,將第一步的QuartzJobBean的子類的全路徑傳給JobDetailBean的jobClass屬性測試

參考代碼以下:網站

<!-- 配置執行工做(作什麼) -->
<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
	<property name="jobClass">
		<value>www.enfp.cc.springquartz.CustomerQuartzJobBean</value>
	</property>
</bean>

2.觸發器Trigger的配置(配置執行時間和執行哪一個工做)<什麼時間作什麼>spa

        Quartz的Trigger類描述了調度時機和頻度,Spring提供了兩個觸發器:SimpleTriggerBean、CronTriggerBean。code

  • SimpleTriggerBean用來指定一個工做運行頻度,以及(可選地)在第一次運行以前等待時間。缺點是該觸發器只能指定工做執行頻度,而不能準確指定什麼時候運行
  • CronTriggerBean能更精確地控制任務的運行時間。如每晚8點發送電子郵件。

(1).使用SimpleTriggerBean調度器(屬性)介紹xml

  • jobDetail:定義工做(作什麼)
  • startDelay:服務啓動後的時間延遲,單位毫秒
  • repeatInterval:重複執行任務的時間間隔,單位毫秒

參考代碼以下:

<!-- 執行效果:啓動任務6秒後執行任務,而且每一個4秒執行一次 -->
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
	<!-- 指定任務(作什麼) -->
	<property name="jobDetail">
		<ref bean="jobDetail" />
	</property>
	<!-- 服務啓動後延遲多少時間執行,單位毫秒 -->
	<property name="startDelay" value="6000"></property>
	<!-- 重複執行任務的時間間隔,單位毫秒 -->
	<property name="repeatInterval" value="4000"></property>
</bean>

(2).使用CronTriggerBean調度器(屬性)介紹

  • jobDetail:定義工做(作什麼)
  • cronExpression:cron表達式(指定執行時間)

     一個cron表達式有至少6個(也多是7個)由空格分隔的時間元素。從左至右,這些元素的定義以下

  •     參數1:秒  0 - 59
  •     參數2:分鐘  0-59
  •     參數3:小時  0-23
  •     參數4:月份中的日期  1-31
  •     參數5:月份 1-12或JAN-DEC
  •     參數6:星期中的日期 1-7或SUN-SAT
  •     參數7:年份1970-2099

    注意: 每個元素均可顯式規定一個值(如6),一個區間(如9-12),一個列表(如9,11,13)或一個通配符(如*)。「月份中的日期」和「星期中的日期」互斥,應經過設置一個問號(?)來代表你不想設置的那個字段

參考代碼以下:

<!-- (觸發器的配置)配置執行時間(或間隔)和執行哪一個工做(什麼時間作什麼) -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
	<!-- (作哪一個工做) -->
	<property name="jobDetail" ref="jobDetail"></property>
	<!-- 配置cron表達式(什麼時間作) -->
	<property name="cronExpression" value="0 * 11 * * ?"></property>
</bean>

(3).啓動觸發器

       使用Spring的SchedulerFactoryBean類可以使用list表示啓動多個觸發器

參考代碼以下:

<!-- 啓動觸發器 -->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
	<property name="triggers">
		<!-- 能夠啓動多個觸發器,因此採用list標籤 -->
		<list>
			<ref bean="cronTrigger"/>
		</list>
	</property>
</bean>

第三步:測試

1.web應用中使用(在web.xml文件加載beans.xml)

2.在java 應用中使用ClassPathXmlApplicationContext類加載beans.xml

參考代碼以下:SpringQuartzTest.java

package www.enfp.cc.springquartz;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringQuartzTest
{
	public static void main(String[] args)
	{
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
				"beans.xml");
	}
}

補充:

 常見一些cron表達式的例子:

  • "0 0 12 * * ?" 天天中午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期間的每1分鐘觸發
  • "0 0/5 14 * * ?" 在天天下午2點到下午2:55期間的每5分鐘觸發
  • "0 0/5 14,18 * * ?" 在天天下午2點到2:55期間和下午6點到6:55期間的每5分鐘觸發
  • "0 0-5 14 * * ?" 在天天下午2點到下午2:05期間的每1分鐘觸發
  • "0 10,44 14 ? 3 WED" 每一年三月的星期三的下午2:10和2:44觸發
  • "0 15 10 ? * MON-FRI" 週一至週五的上午10:15觸發
  • "0 15 10 15 * ?" 每個月15日上午10:15觸發
  • "0 15 10 L * ?" 每個月最後一日的上午10:15觸發
  • "0 15 10 ? * 6L" 每個月的最後一個星期五上午10:15觸發
  • "0 15 10 ? * 6L 2002-2005" 2002年至2005年的每個月的最後一個星期五上午10:15觸發
  • "0 15 10 ? * 6#3" 每個月的第三個星期五上午10:15觸發
  • 天天早上6點
  • 0 6 * * *
  • 每兩個小時
  • 0 */2 * * *
  • 晚上11點到早上8點之間每兩個小時,早上八點
  • 0 23-7/2,8 * * *
  • 每月的4號和每一個禮拜的禮拜一到禮拜三的早上11點
  • 0 11 4 * 1-3
  • 1月1日早上4點
  • 0 4 1 1 *
相關文章
相關標籤/搜索