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

相关文章
相关标签/搜索