Spring+Quartz(一)

Quartz是一個很是優秀的任務調度引擎,詳情請見官網:http://www.quartz-scheduler.org/java

而Spring很好地集成了Quartz,爲企業級的任務調度提供了方便。spring

 

下面先看一個實現了Job接口的任務HelloWorldJob:併發

Java代碼app

package com.springQuartz.example;ide

import java.util.Map;測試

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;spa

public class HelloWorldJob implements Job{code

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        
        Map properties = context.getMergedJobDataMap();
        
        System.out.println("Hello World!");
        System.out.println("Previous Fire Time: "+context.getPreviousFireTime());//上次觸發任務的時間
        System.out.println("Current Fire Time: "+context.getFireTime());//固然觸發時間
        System.out.println("Next Fire Time: "+context.getNextFireTime());//下次觸發時間
        
        System.out.println(properties.get("message"));
        System.out.println();
    }
    
}xml

 

這個Job輸出"HelloWorld",同時輸出上次、本次及下次觸發的時間。對象

 

咱們看一下在applicationContext.xml中的配置:

Xml代碼

<bean id="job" class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="jobClass" value="com.springQuartz.example.HelloWorldJob"/>
    <property name="jobDataAsMap">
         <map>
            <entry key="triggerMessage" value="Job Message In JobDetail"/> <!--設置JobDetail中的值-->
         </map>
    </property>
</bean>
    
<bean id="trigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
    <property name="jobDetail" ref="job"/> <!--觸發的job引用-->
    <property name="startDelay" value="1000"/> <!--設置延遲1秒後運行-->
    <property name="repeatInterval" value="10000"/> <!--設置每10秒觸發一次-->
    <property name="jobDataAsMap">
          <map>
          <entry key="triggerMessage" value="Job Message From Trigger"/> <!--設置Trigger中的值-->
          </map>
    </property>
</bean>

<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref local="trigger"/>    
        </list>
    </property>
</bean>

 

咱們將HelloWorldJob實現成JobDetailBean類,並配置觸發器simpleTriggerBean

 

最後咱們的測試類:

Java代碼

package com.springQuartz.test;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    public static void main(String args[]){
        BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
    }
}

 

運行結果以下:

運行結果代碼

2011-01-16 20:48:18,437 INFO - Starting Quartz Scheduler now
Hello World!
Previous Fire Time: null
Current Fire Time: Sun Jan 16 20:48:19 CST 2011
Next Fire Time: Sun Jan 16 20:48:29 CST 2011
Job Message From Trigger

Hello World!
Previous Fire Time: Sun Jan 16 20:48:19 CST 2011
Current Fire Time: Sun Jan 16 20:48:29 CST 2011
Next Fire Time: Sun Jan 16 20:48:39 CST 2011
Job Message From Trigger

  1.  

下面說明幾點:

1)首次觸發是輸出的Previous Fire Time爲null

2)jobDataAsMap的說明:在HelloWorldJob.java中getMergedJobDataMap是JobDetail和 Trigger上的JobDataMap的合併,二者數據若是衝突,則Trigger上的數據將覆蓋JobDetail中的。運行結果也證實了,咱們在 Job中設置的值沒有輸出,而輸出了"Job Message From Trigger"。

3)咱們看到HelloWorldJob實現了Job接口,代碼上依賴了Quartz的接口

 

下面咱們討論另一種更廣泛的,去除接口依賴的實現

 

主要的applicationContext.xml文件的配置

Xml代碼

<bean id="jobService" class="com.springQuartz.service.JobServiceImpl">
</bean>
    
<bean id="invokeJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject">
        <ref bean="jobService" /> <!--目標Job-->
    </property>
    <property name="targetMethod">
        <value>JobServiceImpl中的特定方法</value> <!--目標方法-->
    </property>
    <property name="concurrent">
        <value>false</value> <!--設置是否同步-->
    </property>
</bean>
    
<bean id="jobServiceCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
    <property name="jobDetail" ref="invokeJob" />
    <property name="cronExpression" value="5/10 * * * * ?" />
</bean>

<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref local="jobServiceCronTrigger"/>
        </list>
    </property>
</bean>

 

 

 

1)首先咱們配置具體的Job信息--JobServiceImpl,這個類能夠不實現Quartz中的Job接口

2)最主要的MethodInvokingJobDetailFactoryBean,能夠使得1)可行

3)相對於上面的例子,咱們使用CronTriggerBean實現trigger,實現更靈活的時間配置

4)默認狀況下,Quartz Jobs是無狀態的,可能致使jobs之間互相的影響。若是你爲相同的JobDetail 指定兩個Trigger, 極可能當第一個job完成以前,第二個job就開始了。若是JobDetail 對象實現了Stateful 接口,就不會發生這樣的事情。 第二個job將不會在第一個job完成以前開始。爲了使得jobs不併發運行,設置MethodInvokingJobDetailFactoryBean 中的concurrent 標記爲false

相關文章
相關標籤/搜索