有時候我們的任務(Job)需要再某些任務完成之後才能進行;例如從舊的數據庫批量導數據的時候;需要現將被其他數據依賴的數據導入新的數據庫;然後再進行關系的導入.。在這種情況下我們就可以使用Quartz的listener來做文章了。
首先我們寫一個主任務的類,命名為MainJob;她的作用是作為一系列任務的開始點。
MainJob.java
package jobs;
import org.apache.log4j.Logger;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class MainJob extends QuartzJobBean {
private Logger logger = Logger.getLogger(getClass());
@Override
protected void executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
// TODO Auto-generated method stub
logger.debug("Just say hi.");
}
}
然後我們新建另外一個任務(SecondJob)作為後續任務:
SecondJob.java
package jobs;
import org.apache.log4j.Logger;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class SecondJob extends QuartzJobBean {
private Logger logger = Logger.getLogger(getClass());
@Override
protected void executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
// TODO Auto-generated method stub
logger.debug("I'm the second job.");
}
}
創建一個TriggerListener,重寫其triggerComplete方法,並且添加一些方便spring注入的屬性和方法。
NextJobTriggerListener.java
package listeners;
import org.apache.log4j.Logger;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.listeners.TriggerListenerSupport;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.scheduling.quartz.SimpleTriggerBean;
public class NextJobTriggerListener extends TriggerListenerSupport {
private Logger logger = Logger.getLogger(getClass());
private String name;
public String getName() {
return this.name;
}
public void setName(String name)
{
this.name=name;
}
private SimpleTriggerBean nextTrigger;
public void setNextTrigger(SimpleTriggerBean nextTrigger) {
this.nextTrigger = nextTrigger;
}
@Override
public void triggerComplete(Trigger trigger, JobExecutionContext context, int code) {
try{
Scheduler schduler=context.getScheduler();
JobDetail nextJob=nextTrigger.getJobDetail();
//查找名稱和即將加入的任務一樣的任務
JobDetail oldJob=schduler.getJobDetail(nextJob.getName(),nextJob.getGroup());
//查找名稱和即將加入的觸發器一樣的觸發器
Trigger oldTrigger=schduler.getTrigger( nextTrigger.getName(),nextTrigger.getGroup());
if(oldJob==null&&oldTrigger==null)//同名的任務和觸發器都不存在
{
logger.debug("inside scheduleJob."+code);
schduler.scheduleJob(nextJob,nextTrigger);
}else//同名的任務或觸發器
{
logger.debug("oldJob==null:"+(oldJob==null));
logger.debug("oldTrigger==null:"+(oldTrigger==null));
}
super.triggerComplete(trigger, context, code);
}catch(Exception e)
{
e.printStackTrace();
}
}
}
配置spring 的applicationContext.xml
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:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
<!-- 主任務 -->
<bean id="mainJob"
class="org.springframework.scheduling.quartz.JobDetailBean">
<!-- 運行的類 -->
<property name="jobClass">
<value>jobs.MainJob</value>
</property>
</bean>
<!-- 主任務的監聽器 -->
<bean id="mainTriggerListener"
class="listeners.NextJobTriggerListener">
<!-- 下個觸發器 -->
<property name="nextTrigger" ref="secondTrigger"></property>
<!-- 監聽器名稱 -->
<property name="name" value="mainTriggerListener"></property>
</bean>
<!-- 主任務的觸發器 -->
<bean id="mainTrigger"
class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail">
<!-- 上面創建的任務調度對象 -->
<ref bean="mainJob" />
</property>
<!-- 啟動60秒後執行任務調度的excute方法 -->
<property name="startDelay">
<value>6000</value>
</property>
<!-- 運行次數 -->
<property name="repeatCount">
<value>0</value>
</property>
<!-- 隔一個小時運行一次(貌似多余,不寫會報錯) -->
<property name="repeatInterval">
<value>3600000</value>
</property>
<property name="triggerListenerNames">
<list>
<value>mainTriggerListener</value>
</list>
</property>
</bean>
<!-- 後續任務 -->
<bean id="secondJob"
class="org.springframework.scheduling.quartz.JobDetailBean">
<!-- 運行的類 -->
<property name="jobClass">
<value>jobs.SecondJob</value>
</property>
</bean>
<!-- 後續任務的觸發器 -->
<bean id="secondTrigger"
class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail">
<!-- 上面創建的任務調度對象 -->
<ref bean="secondJob" />
</property>
<!-- 啟動6秒後執行任務調度的excute方法 -->
<property name="startDelay">
<value>6000</value>
</property>
<!-- 運行次數 -->
<property name="repeatCount">
<value>0</value>
</property>
<!-- 隔一個小時運行一次(貌似多余,不寫會報錯) -->
<property name="repeatInterval">
<!--
<value>3600000</value>
-->
<value>6000</value>
</property>
</bean>
<!-- 任務調度工廠類 -->
<bean
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- 這一部分的配置不用管 -->
<property name="quartzProperties">
<props>
<prop key="org.quartz.threadPool.class">
org.quartz.simpl.SimpleThreadPool
</prop>
<prop key="org.quartz.threadPool.threadCount">10</prop>
<prop key="org.quartz.threadPool.threadPriority">
5
</prop>
<prop
key="org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread">
true
</prop>
</props>
</property>
<!-- 觸發器,可以放一大堆觸發器 -->
<property name="triggers">
<list>
<!-- 在這裡加 -->
<ref bean="mainTrigger"/>
</list>
</property>
<property name="triggerListeners">
<list>
<!-- 觸發器的監聽器 -->
<ref bean="mainTriggerListener"/>
</list>
</property>
</bean>
</beans>
開啟服務器,輸出
DEBUG [MainJob.executeInternal(14)] Just say hi.
DEBUG [NextJobTriggerListener.triggerComplete(38)] inside scheduleJob.3
DEBUG [SecondJob.executeInternal(14)] I'm the second job.
DEBUG [NextJobTriggerListener.triggerComplete(43)] oldJob==null:false
DEBUG [NextJobTriggerListener.triggerComplete(44)] oldTrigger==null:false
另外這裡一個任務只綁定了一個簡單的觸發器,這樣做是為了比較方便地可以檢測到任務完成的情況;至於任務的具體內容就任由大家發揮了。寫這篇文章希望能有人在其中獲得啟發。