Spring中定时任务的实现方式

分类

实现的技术

  1. Java自带的java.util.Timer类。可以按照某一个频度执行,但不能在指定时间运行。

  2. spring自带的task: 轻量级的quartz

  3. Quartz: 相对task强大一些,对于服务器集群环境,可以保证仅一台服务器执行定时任务

作业类的继承方式

  1. 作业类继承指定的作业类基类: quartz中继
    org.springframework.scheduling.quartz.QuartzJobBean;
    Timer中继承java.util.TimerTask

  2. 作业类是普通的java类,不需要继承自任何基类

调度时间来讲

  1. 每隔指定时间则触发一次,quartz中的
    org.springframework.scheduling.quartz.SimpleTriggerBean

  2. 每到指定时间则触发一次,quartz中的
    org.springframework.scheduling.quartz.CronTriggerBean

使用说明



  下面就Quartz和Spring task来详细讲解一下使用方式,都是介绍作业类是普通的java类的实现方式。

Spring Task

  配置如下即可

<!-- 定义一个ThreadPoolTaskScheduler,并可以指定线程池的大小,即pool-size.所有任务队列都将会在指定大小的线程池中运行 -->
<task:scheduler id="schedulerOfTask" pool-size="40"/>
<task:scheduled-tasks scheduler="schedulerOfTask">
<!-- 每天0点10分,执行expiredTask Bean中的methodName方法 -->
<task:scheduled ref="expiredTask" method="methodName" cron="0 10 0 * * ?"/>
<!-- 每隔30s,执行expiredTask2 Bean中的methodName方法 -->
<task:scheduled ref="expiredTask2" method="methodName" fixed-rate="10000" fixed-rate="30000"/>
</task:scheduled-tasks>
<!-- 任务类 -->
<bean id="expiredTask" class="com.gether.test.task.ExpiredTask">
<property name="runJob" value="true"/>
</bean>
<bean id="expiredTask2" class="com.gether.test.task.ExpiredTask2">
<property name="runJob" value="true"/>
</bean>

initial-delay: 表示第一次运行前需要延迟的时间,单位是毫秒

fixed-delay: 表示从上一个任务完成到下一个任务开始的间隔, 单位是毫秒

fixed-rate: 表示从上一个任务开始到下一个任务开始的间隔, 单位是毫秒(如果某次任务开始时上次任务还没有结束,那么在上次任务执行完成时,当前任务会立即执行)

Quartz

配置调度工厂

<bean id="startQuartz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger" />
<ref bean="simpleTrigger" />
</list>
</property>
</bean>

配置触发器

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail">
<ref bean="cornTask" />
</property>
<property name="cronExpression">
<value>*/30 * * * * ?</value>
</property>
</bean>
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="beanTask" />
<property name="startDelay" value="0" />
<!-- 每2秒调度一次 -->
<property name="repeatInterval" value="2000" />
</bean>
<bean id="beanTask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 调用的类 -->
<property name="targetObject">
<ref bean="taskService" />
</property>
<!-- 调用类中的方法 -->
<property name="targetMethod">
<value>beanMethod</value>
</property>
</bean>
<bean id="taskService" class="com.gether.test.task.impl.TaskServiceImpl" />

小结



  根据项目的需要选择不同的方案,个人一般建议使用Spring Task实现定时任务,如果有集群的需要,某些定时任务可以仅配置一台机器执行。

  如果使用Quartz,采用数据库存储定时任务等信息的话,那么你的数据将需要导入Quartz相关的一些表,显得数据表比较杂乱,不建议使用。可以采用RAMJobStore的方式。