Spring task scheduling

Spring itself does not provide direct implementation of task scheduling, but Spring provides the integration of Timer and Quartz under the premise of its own framework principles. Using the spring container, you can easily schedule tasks for existing beans.

Before explaining how to use task scheduling in spring, let's first take a look at Timer itself.

The Timer provided in the JDK is a simpler scheduling method than Quartz. Of course, Quartz provides more powerful functions. Compared to Timer, Quartz's unique features include:

1. Support persistent operations. Quartz allows the job status to be persisted, and it can also maintain a consistent job status between restarts of the application server.

2. Cron-like timing support. Through Quartz's CronTrigger, Quartz allows the use of a Unix-like scheduling method to specify when the job is executed. The Timer only allows the implementation of time and interval specifications.

3. Thread processing model. Timer uses a single thread to implement jobs, while Quartz uses a thread pool to execute jobs. The size and implementation of the thread pool can be specified with Quartz properties.

4. Provide a mature event model for monitoring all aspects of the scheduling system including schedulers, triggers and jobs.

5. In addition, Quartz also provides a misfire instruction to specify what to do when the task is not activated normally. Plug-in support is provided, and servlet is provided for initialization.

Spring provides a consistent way to support these two scheduling mechanisms.

1) First look at Timer. Using Timer in spring is different from using the original Eco Timer. The easiest way in spring is to use the MethodInvokingTimerTaskFactoryBean method to create tasks. The configuration is as follows

<bean id="methodInvokingTask" class="org.springframework.scheduling.timer.MethodI/nvokingTimerTaskFactoryBean">

      <property name="targetObject"> <ref bean="exampleBusinessObject"/></property>

      <property name="targetMethod"> <value>doSomething</value></property>

</bean>

The above configuration will create a TimerTask, call idoSomething of exampleBusinessObject.

The next thing that needs to be configured is the scheduling strategy of the timerTask:

<bean id="scheduledTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">

      <property name="delay">

               <value>60000</value>

      </property>

      <property name="period">

               <value>60000</value>

       </property>

       <property name="timerTask">

               <ref bean="methodInvokingTask"/>

        </property>

</bean>

The above two configurations specify what tasks to run and when to run, and now these tasks need to be scheduled:

<bean id="timerFactory" class="org.spring.framework.Scheduling.timer.TimerFactoryBean">

      <property name="ScheduledTimerTask">

             <list>

                  <ref local="ScheduledTask"/>

              </list>

      </property>

</bean>

TimerFactoryBean允许多个ScheduledTask,它会创建和管理Timer实例。

我们除了使用methodInvokingTask这种非侵入方式的TimeTask而外,我们还可以使用自己定义的TimerTask。

Package org.springframework.prospring.scheduling;

public class CustomTask extends TimerTask{   

      public void run(){// do something}
 }

然后直接以spring bean方式配置,替换methodInvokingTask。

2)然后来看看使用Quartz对上述任务的配置。

 

<bean id="methodInvokingJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">

      <property name="targetObject"> <ref bean="exampleBusinessObject"/></property>

      <property name="targetMethod"> <value>doSomething</value></property>

</bean>

<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">

       <property name="startDelay"><value>6000</value></property>

       <property name="repeatInterval"><value>6000</value></property>

</bean>

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

       <property name="triggers">

              <list><ref local="simpleTrigger"/></list>

       </property>

</bean>

在Timer中只有两个概念TimerTask和Timer,至于调度细节是通过重载Timer的schedule方法来制定,只是在spring集成中spring将其分解成为了三个步骤。而Quartz确有四个概念,Scheduler(调度器)Trigger(触发器)Job(任务)JobDetail(工作细节),接下来详细来看这四个元素,以及spring对它们的支持:

job

job是具体任务的实现,需要继承自QuartzJobBean并在executeInternal方法中实现具体的任务细节。该方法接受一个参数,JobExcutionContext,其中包含了几乎所有信息的引用,以及需要存放的数据,以供在作业执行之间传递信息。实例代码如下:

package org.springframework.prospring.scheduling;

 

public class ExampleJob extends QuartzJobBean{

      private long lastExecutionDate;

      public void setListExecutionDate(long lastExecutionDate){

            this.lastExecutionDate = lastExecutionDate;

      }

      protected void executeInternal(JobExcutionContext context){

            //do some thing

            // read or write data

            JobDataMap map = context,getJobDetail().getJobDataMap();

            map.put(”lastExecutionDate",System.currentTimeMills());

      }

}

该类的初始化时在Quartz中进行的,需要首先包裹在JobDetail中,JobDetail中负责持有当前任务的相关默认数据。配置如下

<bean id="exampleJobBean" class="org.springframework.quartz.JobDetailBean">

       <property name="name"><value>example</value>

       <property name="group"><value>examples</value>

       ......

       <property name="jobClass">

              <value>org.springframework.prospring.scheduling.ExampleJob</value>

       </property>

<bean>

触发器,触发器中描述了作业的触发策略。之前的例子中已经提到一种方式,其实Quartz提供了两种方式触发器,simple和cron。cron使用类似于Unix中的调度描述表达式,配置如下:

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">

       <property name="jobDetail">

              <ref bean="exampleJobDetail"/>

       </property>

       <property name="cronExpression">

               <value>0 15 4 ? * MON-FRI</value>

       </property> 

<bean>

触发器中还可以指定哑火指令,指定监听器。

调度器,作为Quartz系统的主要部分,它维护了所有的作业细节和关联触发器的一个注册项;它在作业被激活的时候,它管理作业的创建和运行,并且负责保持作业的状态信息。


Spring本身不提供任务调度的直接实现,但是Spring在自身框架原则前提下提供了对Timer和Quartz的集成。使用spring容器可以轻松地对既有的bean进行任务调度。

在说明如何在spring中使用任务调度之前,首先来看看Timer本身。

JDK中提供的Timer是比Quartz更为简单的调度方法,当然,Quartz提供了更为强大的功能。相比Timer,Quartz独有的特性包括:

1、支持持久性作业。Quartz允许将作业状态持久化,在应用服务器重启之间,也能够保持一致的作业状态。

2、类Cron的定时支持。通过Quartz的CronTrigger,Quartz允许使用类似Unix调度的方式来制定作业何时执行。而Timer只允许执行时间和间隔的规范。

3、线程处理模型。Timer是使用单线程实现作业,而Quartz使用线程池来执行作业。线程池的大小以及实现都可以用Quartz属性来制定。

4、提供成熟的事件模型,用于监控调度系统的各个方面包括调度器,触发器和作业。

5、另外Quartz还提供了哑火指令用于指定当任务没有正常激活该做什么。提供了插件支持,提供了servlet用以初始化。

Spring提供了一致的方式来支持这两种调度机制。

1)首先来看Timer,在spring中使用Timer与使用原生态的Timer有所不同,在spring最简单的方法就是使用MethodInvokingTimerTaskFactoryBean方法来创建任务,配置如下

<bean id="methodInvokingTask" class="org.springframework.scheduling.timer.MethodI/nvokingTimerTaskFactoryBean">

      <property name="targetObject"> <ref bean="exampleBusinessObject"/></property>

      <property name="targetMethod"> <value>doSomething</value></property>

</bean>

以上的配置就会创建一个TimerTask,调用exampleBusinessObject的idoSomething。

接下来需要配置的是该timerTask的调度策略:

<bean id="scheduledTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">

      <property name="delay">

               <value>60000</value>

      </property>

      <property name="period">

               <value>60000</value>

       </property>

       <property name="timerTask">

               <ref bean="methodInvokingTask"/>

        </property>

</bean>

以上两个配置指定了要运行什么任务,何时运行,现在还需要预定这些任务:

<bean id="timerFactory" class="org.spring.framework.Scheduling.timer.TimerFactoryBean">

      <property name="ScheduledTimerTask">

             <list>

                  <ref local="ScheduledTask"/>

              </list>

      </property>

</bean>

TimerFactoryBean允许多个ScheduledTask,它会创建和管理Timer实例。

我们除了使用methodInvokingTask这种非侵入方式的TimeTask而外,我们还可以使用自己定义的TimerTask。

Package org.springframework.prospring.scheduling;

public class CustomTask extends TimerTask{   

      public void run(){// do something}
 }

然后直接以spring bean方式配置,替换methodInvokingTask。

2)然后来看看使用Quartz对上述任务的配置。

 

<bean id="methodInvokingJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">

      <property name="targetObject"> <ref bean="exampleBusinessObject"/></property>

      <property name="targetMethod"> <value>doSomething</value></property>

</bean>

<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">

       <property name="startDelay"><value>6000</value></property>

       <property name="repeatInterval"><value>6000</value></property>

</bean>

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

       <property name="triggers">

              <list><ref local="simpleTrigger"/></list>

       </property>

</bean>

在Timer中只有两个概念TimerTask和Timer,至于调度细节是通过重载Timer的schedule方法来制定,只是在spring集成中spring将其分解成为了三个步骤。而Quartz确有四个概念,Scheduler(调度器)Trigger(触发器)Job(任务)JobDetail(工作细节),接下来详细来看这四个元素,以及spring对它们的支持:

job

job是具体任务的实现,需要继承自QuartzJobBean并在executeInternal方法中实现具体的任务细节。该方法接受一个参数,JobExcutionContext,其中包含了几乎所有信息的引用,以及需要存放的数据,以供在作业执行之间传递信息。实例代码如下:

package org.springframework.prospring.scheduling;

 

public class ExampleJob extends QuartzJobBean{

      private long lastExecutionDate;

      public void setListExecutionDate(long lastExecutionDate){

            this.lastExecutionDate = lastExecutionDate;

      }

      protected void executeInternal(JobExcutionContext context){

            //do some thing

            // read or write data

            JobDataMap map = context,getJobDetail().getJobDataMap();

            map.put(”lastExecutionDate",System.currentTimeMills());

      }

}

该类的初始化时在Quartz中进行的,需要首先包裹在JobDetail中,JobDetail中负责持有当前任务的相关默认数据。配置如下

<bean id="exampleJobBean" class="org.springframework.quartz.JobDetailBean">

       <property name="name"><value>example</value>

       <property name="group"><value>examples</value>

       ......

       <property name="jobClass">

              <value>org.springframework.prospring.scheduling.ExampleJob</value>

       </property>

<bean>

触发器,触发器中描述了作业的触发策略。之前的例子中已经提到一种方式,其实Quartz提供了两种方式触发器,simple和cron。cron使用类似于Unix中的调度描述表达式,配置如下:

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">

       <property name="jobDetail">

              <ref bean="exampleJobDetail"/>

       </property>

       <property name="cronExpression">

               <value>0 15 4 ? * MON-FRI</value>

       </property> 

<bean>

触发器中还可以指定哑火指令,指定监听器。

调度器,作为Quartz系统的主要部分,它维护了所有的作业细节和关联触发器的一个注册项;它在作业被激活的时候,它管理作业的创建和运行,并且负责保持作业的状态信息。

Guess you like

Origin blog.csdn.net/Amos_liu/article/details/50771170