Spring整合Quartz实现定时任务调度的方法

 更新时间:2016年11月25日 09:20:25   投稿:jingxian  
下面小编就为大家带来一篇Spring整合Quartz实现定时任务调度的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

最近项目中需要实现定时执行任务,比如定时计算会员的积分、调用第三方接口等,由于项目采用spring框架,所以这里结合spring框架来介绍。

编写作业类

即普通的pojo,如下:

package com.pcmall.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TaskA {
	private static Logger logger = LoggerFactory.getLogger(TaskA.class);
	public void taskA1(){
		for(int i=0;i<100;i++){
			System.out.println("----A1----" + i);
		}
	}
	public void taskA2(){
		for(int i=0;i<100;i++){
			System.out.println("----A2----" + i);
		}
	}
}

在spring配置文件设置具体的任务

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<bean id="taskA" class="com.pcmall.task.TaskA"></bean>
	<bean id="taskB" class="com.pcmall.task.TaskB"></bean>
	
	<bean id="taskJobA1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<property name="targetObject" ref="taskA"></property>
		<property name="targetMethod" value="taskA1"></property>
		<property name="concurrent" value="false"></property>
	</bean>
	<bean id="taskJobA2" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<property name="targetObject" ref="taskA"></property>
		<property name="targetMethod" value="taskA2"></property>
		<property name="concurrent" value="false"></property>
	</bean>
	<bean id="taskJobB1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<property name="targetObject" ref="taskB"></property>
		<property name="targetMethod" value="taskB1"></property>
		<property name="concurrent" value="false"></property>
	</bean>
	<bean id="taskJobB2" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<property name="targetObject" ref="taskB"></property>
		<property name="targetMethod" value="taskB2"></property>
		<property name="concurrent" value="false"></property>
	</bean>
	
	<bean id="taskA1Trigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
		<property name="jobDetail">
			<ref bean="taskJobA1" />
		</property>
		<property name="cronExpression">
			<value>0 0/1 * * * ?</value>
		</property>
	</bean>
	<bean id="taskA2Trigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
		<property name="jobDetail">
			<ref bean="taskJobA2" />
		</property>
		<property name="cronExpression">
			<value>0 0/2 * * * ?</value>
		</property>
	</bean>
	
	<bean id="taskB1Trigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
		<property name="jobDetail">
			<ref bean="taskJobB1" />
		</property>
		<property name="cronExpression">
			<value>0 0/1 * * * ?</value>
		</property>
	</bean>

	<bean id="taskB2Trigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
		<property name="jobDetail">
			<ref bean="taskJobB2" />
		</property>
		<property name="cronExpression">
			<value>0 0/2 * * * ?</value>
		</property>
	</bean>

	<bean id="scheduler"
		class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="triggers">
			<list>
				<ref bean="taskA1Trigger" />
				<ref bean="taskA2Trigger" />
				<ref bean="taskB1Trigger" />
				<ref bean="taskB2Trigger" />
			</list>
		</property>
	</bean>
</beans>

注意

一个触发器只能触发一个Job,不过一个Job可以有多个Trigger触发,这回带来并发问题。在Quartz中,如果你不想并发执行一个同一个 Job,你可以实现StatefulJob,而不是Job。在Spring中如果使用 MethodInvokingJobDetailFactoryBean,可以通过设置concurrent="false"属性来实现。

尾注

在Spring中使用Quartz而不是单独的一个应用的好处包括:

将所有的任务调度设置放在同一个地方,是任务易于维护。

只对Job编码,Trigger和Scheduler可以通过配置设置

可以使用Pojo Java Bean执行job,而无需实现Job接口

Cron表达式的详细用法

字段 允许值 允许的特殊字符

秒 0-59 , - * /
分 0-59 , - * /
小时 0-23 , - * /
日期 1-31 , - * ? / L W C
月份 1-12 或者 JAN-DEC , - * /
星期 1-7 或者 SUN-SAT , - * ? / L C #
年(可选)留空, 1970-2099 , - * /

例子:

0/5 * * * * ? : 每5秒执行一次

“”字符被用来指定所有的值。如:""在分钟的字段域里表示“每分钟”。

“?”字符只在日期域和星期域中使用。它被用来指定“非明确的值”。当你需要通过在这两个域中的一个来指定一些东西的时候,它是有用的。看下面的例子你就会明白。

月份中的日期和星期中的日期这两个元素时互斥的一起应该通过设置一个问号来表明不想设置那个字段。

“-”字符被用来指定一个范围。如:“10-12”在小时域意味着“10点、11点、12点”。

“,”字符被用来指定另外的值。如:“MON,WED,FRI”在星期域里表示”星期一、星期三、星期五”。

“/”字符用于指定增量。如:“0/15”在秒域意思是每分钟的0,15,30和45秒。“5/15”在分钟域表示每小时的5,20,35和50。符号“”在“/”前面(如:/10)等价于0在“/”前面(如:0/10)。记住一条本质:表达式的每个数值域都是一个有最大值和最小值的集合,如:秒域和分钟域的集合是0-59,日期域是 1-31,月份域是1-12。字符“/”可以帮助你在每个字符域中取相应的数值。如:“7/6”在月份域的时候只有当7月的时候才会触发,并不是表示每个 6月。

L是‘last'的省略写法可以表示day-of-month和day-of-week域,但在两个字段中的意思不同,例如day-of- month域中表示一个月的最后一天。如果在day-of-week域表示‘7'或者‘SAT',如果在day-of-week域中前面加上数字,它表示一个月的最后几天,例如‘6L'就表示一个月的最后一个星期五。

字符“W”只允许日期域出现。这个字符用于指定日期的最近工作日。例如:如果你在日期域中写 “15W”,表示:这个月15号最近的工作日。所以,如果15号是周六,则任务会在14号触发。如果15好是周日,则任务会在周一也就是16号触发。如果是在日期域填写“1W”即使1号是周六,那么任务也只会在下周一,也就是3号触发,“W”字符指定的最近工作日是不能够跨月份的。字符“W”只能配合一个单独的数值使用,不能够是一个数字段,如:1-15W是错误的。

“L”和“W”可以在日期域中联合使用,LW表示这个月最后一周的工作日。

字符“#”只允许在星期域中出现。这个字符用于指定本月的某某天。例如:“6#3”表示本月第三周的星期五(6表示星期五,3表示第三周)。“2#1”表示本月第一周的星期一。“4#5”表示第五周的星期三。

字符“C”允许在日期域和星期域出现。这个字符依靠一个指定的“日历”。也就是说这个表达式的值依赖于相关的“日历”的计算结果,如果没有“日历” 关联,则等价于所有包含的“日历”。如:日期域是“5C”表示关联“日历”中第一天,或者这个月开始的第一天的后5天。星期域是“1C”表示关联“日历” 中第一天,或者星期的第一天的后1天,也就是周日的后一天(周一)。

表达式举例

"0 0 12 * * ?" 每天中午12点触发
"0 15 10 ? * *" 每天上午10:15触发
"0 15 10 * * ?" 每天上午10:15触发
"0 15 10 * * ? *" 每天上午10:15触发
"0 15 10 * * ? 2005" 2005年的每天上午10:15触发
"0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发
"0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发
"0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
"0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发
"0 15 10 15 * ?" 每月15日上午10:15触发
"0 15 10 L * ?" 每月最后一日的上午10:15触发
"0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发 
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发

以上这篇Spring整合Quartz实现定时任务调度的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring Boot JPA中使用@Entity和@Table的实现

    Spring Boot JPA中使用@Entity和@Table的实现

    这篇文章主要介绍了Spring Boot JPA中使用@Entity和@Table的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • Ribbon单独使用,配置自动重试,实现负载均衡和高可用方式

    Ribbon单独使用,配置自动重试,实现负载均衡和高可用方式

    这篇文章主要介绍了Ribbon单独使用,配置自动重试,实现负载均衡和高可用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • Git工具 conflict冲突问题解决方案

    Git工具 conflict冲突问题解决方案

    这篇文章主要介绍了Git工具 conflict冲突问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • java保留小数的四种实现方法

    java保留小数的四种实现方法

    这篇文章主要为大家详细介绍了java保留小数的四种实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • MyBatis 动态SQL和缓存机制实例详解

    MyBatis 动态SQL和缓存机制实例详解

    这篇文章主要介绍了MyBatis 动态SQL和缓存机制实例详解,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-09-09
  • 浅谈@PostConstruct不被调用的原因

    浅谈@PostConstruct不被调用的原因

    这篇文章主要介绍了浅谈@PostConstruct不被调用的原因及分析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • SpringBoot使用YML文件进行多环境配置的三种方法

    SpringBoot使用YML文件进行多环境配置的三种方法

    SpringBoot通过其灵活的配置机制,使得在不同环境中管理应用设置变得简单,尤其是使用YAML文件进行配置,它提供了一种简洁、易读的方式来定义应用的配置,本文将探讨在SpringBoot中使用YAML文件进行多环境配置的三种方法,需要的朋友可以参考下
    2024-04-04
  • Activiti流程图查看实例

    Activiti流程图查看实例

    这篇文章主要介绍了Activiti流程图查看实例,需要的朋友可以参考下
    2014-08-08
  • SpringSecurity rememberme功能实现过程解析

    SpringSecurity rememberme功能实现过程解析

    这篇文章主要介绍了SpringSecurity rememberme功能实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • 详解Java redis中缓存穿透 缓存击穿 雪崩三种现象以及解决方法

    详解Java redis中缓存穿透 缓存击穿 雪崩三种现象以及解决方法

    缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大
    2022-01-01

最新评论