Quartz與Spring的整合使用——建立JobDetail的方式及Trigger

以前說到過Quartz的基本使用(猛戳這裏看文章),在實際使用中,咱們一般會將定時任務交由spring容器來管理,因此今天咱們來講說Quartz與spring的整合。java

我們仍是按照Quartz的三大元素的順序來聊聊整合使用。程序員

做業任務

在spring中對於Quartz的做業任務管理主要提供了兩種方式,JobDetailFactoryBean和MethodInvokingJobDetailFactoryBean,它們都在org.springframework.scheduling.quartz這個包下。下面咱們來看看它們的使用。spring

  • JobDetailFactoryBean

spring對這個類的解釋爲:A Spring FactoryBean for creating a Quartz JobDetail instance, supporting bean-style usage for JobDetail configuration. 
一個用於建立Quartz JobDetail實例的,支持以bean定義風格來配置JobDetail的工廠bean。併發

對於在spring中的使用也是很簡單,首先咱們須要建立一個具體的做業任務的實現類。使用JobDetailFactoryBean來管理做業任務時,咱們的做業任務實現類須要繼承QuartzJobBean類,並覆蓋其executeInternal方法。就像下面這樣。app

public class SimpleJob extends QuartzJobBean {

    @Override
    protected void executeInternal(JobExecutionContext arg0)
            throws JobExecutionException {
        System.out.println("如今時間爲:"+new Date());
        //能夠經過上下文獲取到JobDataMap,這裏面能夠存放一些參數類型的數據
        JobDataMap dataMap=arg0.getMergedJobDataMap();
        String wish=(String) dataMap.get("wish");
        System.out.println(wish);
    }
}

而後就在spring容器中以下配置:ide

<bean id="jobDetailFactoryBeanExample" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    <!-- 參考源碼,咱們能夠看到屬性jobClass爲Class類型,因此不能使用ref來引用一個bean,不然就會由於不能將bean轉換爲Class類型而出現異常。
        <property name="jobClass" ref="simpleJob"/>
        必須使用value對jobClass賦值。 
        <property name="jobClass" value="com.earl.quartz.spring.job.SimpleJob"/>    
    -->
    <property name="jobClass" value="com.earl.quartz.spring.job.SimpleJob"/>
    <!-- 這裏設置的jobDataAsMap能夠傳遞一些參數給做業任務 -->
    <property name="jobDataAsMap">
        <map>
            <entry key="wish" value="hello"/>
        </map>
    </property>
</bean>
  • MethodInvokingJobDetailFactoryBean

spring對這個類的解釋:FactoryBean that exposes a JobDetail object which delegates job execution to a specified (static or non-static) method. 
這個FactoryBean提供JobDetail對象,這個對象能夠指定做業任務的執行方法。spa

由於能夠指定做業調度時執行的內容,因此使用起來就比JobDetailFactoryBean更加的靈活方便。首先咱們仍是建立一個做業任務的具體實現類,這個實現類就不須要繼承或實現其餘的父類,只須要將咱們想要執行的做業任務聲明在具體的方法中便可。以下:.net

public class ExampleJob{
    public void execute(){
        System.out.println("如今是"+new SimpleDateFormat("yyyy年MM月dd日 HH時mm分ss秒").format(new Date()));
    }
}

而後在spring容器中以下配置便可:code

<!-- 
    若是兩個觸發器觸發同一個做業,那麼第二個做業可能在第一個做業完成以前被觸發。
    將做業類實現StatefulJob接口就能夠避免這種狀況。
    將concurrent設置爲false能夠避免併發的發生。
-->
<!-- 使用MethodInvokingJobDetailFactoryBean來建立做業對象 -->
<bean id="exampleJob" class="com.earl.quartz.spring.job.ExampleJob"/>
<bean id="methodInvokingJobDetailFactoryBeanExample" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 目標對象,指的是做業任務的實現類 -->
<property name="targetObject" ref="exampleJob"/>
<!-- 目標方法,指的是指定實現類中的哪一個方法做爲調度時的執行方法 -->
<property name="targetMethod" value="execute"/>
<!-- 是否併發 -->
<property name="concurrent" value="false"/>
</bean>

以上就是做業任務的相關內容,下面咱們來看看觸發器這個可愛的小東東。orm

觸發器

在spring中,觸發器也分爲simpleTrigger和cronTrigger,並且它們的使用也是很是簡單,只須要配置一個bean元素便可。下面咱們分別看看它們二者的配置:

  • simpleTrigger
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
    <!-- 這裏的JobDetail指的就是咱們配置的做業任務的bean -->
    <property name="jobDetail" ref="methodInvokingJobDetailFactoryBeanExample" />
    <!-- 延遲5秒開始 -->
    <property name="startDelay" value="5000"></property>
    <!-- 每3秒重複一次 -->
       <property name="repeatInterval" value="3000"></property>     
</bean>
  • cronTrigger
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <!-- 這裏的JobDetail指的就是咱們配置的做業任務的bean -->
    <property name="jobDetail" ref="jobDetailFactoryBeanExample"/>
    <!--cronExpression,cron表達式-->
    <property name="cronExpression" value="40 52 17 * * ?"/>
</bean>

以上就是觸發器的基本配置,上述兩個觸發器的工廠bean還有一些其餘的屬性,例如jobDataMap,priority等等。若是有須要,您能夠參考相關的文檔。

調度程序

最後,最簡單的莫過於做業調度程序了,在spring中只須要這樣配置便可:

<bean id="startQuartz" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
    <!--指定使用哪些觸發器,spring會去調度觸發相應的觸發器,進而對做業任務進行調度處理-->
    <property name="triggers">
        <list>
<!--                <ref bean="simpleTrigger"/> -->
            <ref bean="cronTrigger"/>
        </list>
    </property>
</bean>

總結

以上就是對Quartz與Spring的整合使用的基本介紹了。整體來講,Quartz的定時任務功能已經很強大了,而spring對其的整合更是讓程序員在使用定時任務是如虎添翼。對於Quartz來講還有不少其餘的功能,例如定時文件掃描,定時發送郵件等等,以後在另一篇文章中再進行詳細介紹。

猛戳這裏下載源代碼 
說明:本文介紹的是Quartz與Spring的整合使用,因此請參考源碼時關注com.earl.quartz.spring包下內容便可,其餘可自行忽略。

 

如何從Job中獲取ApplicationContext對象:

在xml配置文件中 加入applicationContextSchedulerContextKey配置

<bean  class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

        <property name="triggers">
            <list>
             <!--   <ref bean="simpleTrigger" />-->
                <ref bean="cronTrigger" />
            </list>
        </property>
        <property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>
    </bean>

value的值 用於Job中獲取application上下文對象。 即設置 APPLICATION_CONTEXT_KEY 的值

public class ScheduledJob extends QuartzJobBean {
    private static final String APPLICATION_CONTEXT_KEY = "applicationContextKey";

    private AnotherBean anotherBean;
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        ApplicationContext applicationContext = null;
        try{
            applicationContext = getApplicationContext(context);
        }catch (Exception e){
            e.printStackTrace();
        }
        if(applicationContext != null){
            System.out.println("applicationContext");
            ((AnotherBean)(applicationContext.getBean("anotherBean"))).printAnotherMessage();
        }
    }
    private ApplicationContext getApplicationContext(JobExecutionContext context) throws Exception {
        ApplicationContext appCtx = null;
        appCtx = (ApplicationContext) context.getScheduler().getContext().get(APPLICATION_CONTEXT_KEY);
        if (appCtx == null) {
            throw new JobExecutionException("No application context available in scheduler context for key \"" + APPLICATION_CONTEXT_KEY + "\"");
        }
        return appCtx;
    }
}
相關文章
相關標籤/搜索