Quartz与Spring的整合使用

Quartz是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制。Quartz允许开发人员根据时间间隔来调度作业。它实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。


简单的说Quartz就是一个定时任务,可以设定需要的时间或者时间间隔让它定时执行。如果是一般简单的任务调度,借助java本身的 java.util.Timer 就可以实现。只不过Quartz的功能更加的强大,配置更加的灵活,还可以集群等。


看看Quartz怎么和spring配合使用吧:


一般一个简单任务只需要以下几个包:commons-beanutils.jar、commons-collections.jar、commons-logging.jar、commons-digester.jar、quartz.jar即可。(可以到网上下载)


如果还需要其他比较特殊的功能,那么对照一下下面的。(学识浅薄,不一定全部都对)


名称必须/备注 
activation.jar主要是 JavaMail 要用到 
commons-beanutils.jar 
commons-collections.jar 
commons-dbcp-1.1.jar是,假如用到数据库作为作业存 
commons-digester.jar假如你使用了某些插件,就需要它
commons-logging.jar 
commons-pool-1.1.jar  
javamail.jar发送 e-mail 用 
jdbc2_0-stdext.jar是,假如用到数据库作为作业存储 
jta.jar是,假如用到数据库作为作业存储 
quartz.jarQuart 框架核心包
servlet.jar假如使用了Servlet 容器,但容器中应该存在 
log4j.jar是,日志 


使用Quartz前需要添加一个properties文件,用来配置Quartz的相关属性,看看:

quartz.properties

# 配置主调度器属性  
org.quartz.scheduler.instanceName = QuartzScheduler  
org.quartz.scheduler.instanceId  = AUTO  
# 配置线程池  
# Quartz线程池的实现类  
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool  
# 线程池的线程数量  
org.quartz.threadPool.threadCount = 1  
# 线程池里线程的优先级  
org.quartz.threadPool.threadPriority = 5  
# 配置作业存储  
org.quartz.jobStore.misfireThreshold = 60000  
org.quartz.jobStore.class =org.quartz.simpl.RAMJobStore



#介绍一些配置信息,好记性不如烂笔头
# Default Properties file for use by StdSchedulerFactory  
# to create a Quartz Scheduler Instance, if a different  
# properties file is not explicitly specified.  
#  
# ===========================================================================  
# Configure Main Scheduler Properties 调度器属性  
# ===========================================================================  
#org.quartz.scheduler.instanceName: DefaultQuartzScheduler  
#org.quartz.scheduler.instanceid:AUTO  
#org.quartz.scheduler.rmi.export: false  
#org.quartz.scheduler.rmi.proxy: false  
#org.quartz.scheduler.wrapJobExecutionInUserTransaction: false  
# ===========================================================================    
# Configure ThreadPool 线程池属性    
# ===========================================================================  
#线程池的实现类(一般使用SimpleThreadPool即可满足几乎所有用户的需求)  
#org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool  
#指定线程数,至少为1(无默认值)(一般设置为1-100直接的整数合适)  
#org.quartz.threadPool.threadCount: 10  
#设置线程的优先级(最大为java.lang.Thread.MAX_PRIORITY 10,最小为Thread.MIN_PRIORITY 1,默认为5)  
#org.quartz.threadPool.threadPriority: 5  
#设置SimpleThreadPool的一些属性  
#设置是否为守护线程  
#org.quartz.threadpool.makethreadsdaemons = false  
#org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true  
#org.quartz.threadpool.threadsinheritgroupofinitializingthread=false  
#线程前缀默认值是:[Scheduler Name]_Worker  
#org.quartz.threadpool.threadnameprefix=swhJobThead;  
# 配置全局监听(TriggerListener,JobListener) 则应用程序可以接收和执行 预定的事件通知  
# ===========================================================================  
# Configuring a Global TriggerListener 配置全局的Trigger监听器  
# MyTriggerListenerClass 类必须有一个无参数的构造函数,和 属性的set方法,目前2.2.x只支持原始数据类型的值(包括字符串)  
# ===========================================================================  
#org.quartz.triggerListener.NAME.class = com.swh.MyTriggerListenerClass  
#org.quartz.triggerListener.NAME.propName = propValue  
#org.quartz.triggerListener.NAME.prop2Name = prop2Value  
# ===========================================================================  
# Configuring a Global JobListener 配置全局的Job监听器  
# MyJobListenerClass 类必须有一个无参数的构造函数,和 属性的set方法,目前2.2.x只支持原始数据类型的值(包括字符串)  
# ===========================================================================  
#org.quartz.jobListener.NAME.class = com.swh.MyJobListenerClass  
#org.quartz.jobListener.NAME.propName = propValue  
#org.quartz.jobListener.NAME.prop2Name = prop2Value  
# ===========================================================================    
# Configure JobStore 存储调度信息(工作,触发器和日历等)  
# ===========================================================================  
# 信息保存时间 默认值60秒  
#org.quartz.jobStore.misfireThreshold: 60000  
#保存job和Trigger的状态信息到内存中的类  
#org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore  
# ===========================================================================    
# Configure SchedulerPlugins 插件属性 配置  
# ===========================================================================  
# 自定义插件    
#org.quartz.plugin.NAME.class = com.swh.MyPluginClass  
#org.quartz.plugin.NAME.propName = propValue  
#org.quartz.plugin.NAME.prop2Name = prop2Value  
#配置trigger执行历史日志(可以看到类的文档和参数列表)  
#org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingTriggerHistoryPlugin    
#org.quartz.plugin.triggHistory.triggerFiredMessage = Trigger {1}.{0} fired job {6}.{5} at: {4, date, HH:mm:ss MM/dd/yyyy}    
#org.quartz.plugin.triggHistory.triggerCompleteMessage = Trigger {1}.{0} completed firing job {6}.{5} at {4, date, HH:mm:ss MM/dd/yyyy} with resulting trigger instruction code: {9}    
#配置job调度插件  quartz_jobs(jobs and triggers内容)的XML文档    
#加载 Job 和 Trigger 信息的类   (1.8之前用:org.quartz.plugins.xml.JobInitializationPlugin)  
#org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin  
#指定存放调度器(Job 和 Trigger)信息的xml文件,默认是classpath下quartz_jobs.xml  
#org.quartz.plugin.jobInitializer.fileNames = my_quartz_job2.xml    
#org.quartz.plugin.jobInitializer.overWriteExistingJobs = false    
#org.quartz.plugin.jobInitializer.failOnFileNotFound = true    
#自动扫描任务单并发现改动的时间间隔,单位为秒  
#org.quartz.plugin.jobInitializer.scanInterval = 10  
#覆盖任务调度器中同名的jobDetail,避免只修改了CronExpression所造成的不能重新生效情况  
#org.quartz.plugin.jobInitializer.wrapInUserTransaction = false  
# ===========================================================================    
# Sample configuration of ShutdownHookPlugin  ShutdownHookPlugin插件的配置样例  
# ===========================================================================  
#org.quartz.plugin.shutdownhook.class = \org.quartz.plugins.management.ShutdownHookPlugin  
#org.quartz.plugin.shutdownhook.cleanShutdown = true  
#  
# Configure RMI Settings 远程服务调用配置  
#  
#如果你想quartz-scheduler出口本身通过RMI作为服务器,然后设置“出口”标志true(默认值为false)。  
#org.quartz.scheduler.rmi.export = false  
#主机上rmi注册表(默认值localhost)  
#org.quartz.scheduler.rmi.registryhost = localhost  
#注册监听端口号(默认值1099)  
#org.quartz.scheduler.rmi.registryport = 1099  
#创建rmi注册,false/never:如果你已经有一个在运行或不想进行创建注册  
# true/as_needed:第一次尝试使用现有的注册,然后再回来进行创建  
# always:先进行创建一个注册,然后再使用回来使用注册  
#org.quartz.scheduler.rmi.createregistry = never  
#Quartz Scheduler服务端端口,默认是随机分配RMI注册表  
#org.quartz.scheduler.rmi.serverport = 1098  
#true:链接远程服务调度(客户端),这个也要指定registryhost和registryport,默认为false  
# 如果export和proxy同时指定为true,则export的设置将被忽略  
#org.quartz.scheduler.rmi.proxy = false  

然后我们需要添加一个spring的配置文件,然后把它import到spring的主配置文件里面:

spring-quartz.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task"
	xmlns:cache="http://www.springframework.org/schema/cache"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	 http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
	 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd  
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd 
     http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd 
     http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">


	<!-- 要调用的工作类,就是你自己创建的类 -->
	<bean id="ehCacheQuartzJob" class="com.im.socket.quartz.EhCacheQuartzJob" />

	<!-- 定义调用对象和调用对象的方法 -->
	<bean id="ehCacheQuartzJobTask"
		class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<!-- 需要调用的类 -->
		<property name="targetObject">
			<ref bean="ehCacheQuartzJob" />
		</property>
		<!-- 需要调用类中的方法 -->
		<property name="targetMethod">
			<value>ehCacheWork</value>
		</property>
	</bean>

	<!-- 定义触发时间 -->
	<bean id="cronTrigger"
		class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
		<property name="jobDetail">
			<ref bean="ehCacheQuartzJobTask" />
		</property>
		<!-- cron表达式,这个可以配置任务调度的时间,待会看下面的介绍 -->
		<property name="cronExpression">
			<value>5/60 * * * * ?</value>
		</property>
	</bean>

	<!-- 总管理类 如果将lazy-init='false'那么容器启动就会执行调度程序 -->
	<bean id="startQuertz" lazy-init="false" autowire="no"
		class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<!-- 读取配置 -->
		<property name="configLocation" value="classpath:quartz.properties" />
		<property name="triggers">
			<list>
				<ref bean="cronTrigger" />
			</list>
		</property>
	</bean>

</beans>

看看需要调用的任务类:

package com.im.socket.quartz;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import com.im.socket.general.Constants;
import com.im.socket.netty.tcp.MessageUtil;
import com.im.socket.protobuf.MessageOuterClass.Message;
import com.im.socket.utils.EHCacheUtil;
import com.im.socket.utils.RedisUtil;
import com.im.utils.DateTimeUtil;

/**
 * 任务调度类
 * 
 * @author kokJuis
 * @version 1.0
 * @date 2016-9-28
 */
public class EhCacheQuartzJob {

	/**
	 * 任务调度的方法
	 * 
	 * @author kokJuis
	 * @version 1.0
	 * @date 2016-9-28
	 */
	public void ehCacheWork() {
		//业务逻辑
	}
}

好了,一般 Quartz使用就是这么简单。看看Cron表达式怎么配置吧:


使用CronTrigger主要的是要掌握Cron表达式。Cron表达式包含6个必要组件和一个可选组件,如下表所示。
 

位置

含义

允许的特殊字符

1

秒(0~59)

, -  *  /

2

分(0~59)

, -  *  /

3

小时(0~24)

, -  *  /

4

日期(1~31)

, -  *  /  ?  L  W  C

5

月(JAN~DEC或1~12)

, -  *  /

6

星期(SUN~SAT或1~7)

, -  *  /  ?  L  C  #

7

年(可选,1970~2099),若为空,表示全部时间范围

, -  *  /

 
特殊字符的含义,见下表。
 

特殊字符

说明

*

通配符,任意值

?

无特定值。通常和其他指定的值一起使用,表示必须显示该值但不能检查

-

范围。e.g.小时部分10-12表示10:00,11:00, 12:00

,

列分隔符。可以让你指定一系列的值。e.g.在星期域中指定MON、TUE和WED

/

增量。表示一个值的增量,e.g.分钟域中0/1表示从0开始,每次增加1min

L

表示Last。它在日期和星期域中表示有所不同。在日期域中,表示这个月的最后一天,而在星期域中,它永远是7(星期六)。当你希望使用星期中某一天时,L字符非常有用。e.g.星期域中6L表示每一个月的最后一个星期五

W

在本月内离当天最近的工作日触发,所谓的最近工作日,即当天到工作日的前后最短距离,如果当天即为工作日,则距离是0;所谓本月内指的是不能跨月取到最近工作日,即使前/后月份的最后一天/第一天确实满足最近工作日。e.g. LW表示本月的最后一个工作日触发,W强烈依赖月份。

#

表示该月的第几个星期,e.g. 1#2表示每一个月的第一个星期一

C

日历值。日期值是根据一个给定的日历计算出来的。在日期域中给定一个20C将在20日(日历包括20日)或20日后日历中包含的第一天(不包括20日)激活触发器。例如在一个星期域中使用6C表示日历中星期五(日历包括星期五)或者第一天(日历不包括星期五)

 
Cron表达式举例:
 
"30 * * * * ?" 每半分钟触发任务
"30 10 * * * ?" 每小时的10分30秒触发任务
"30 10 1 * * ?" 每天1点10分30秒触发任务
"30 10 1 20 * ?" 每月20号1点10分30秒触发任务
"30 10 1 20 10 ? *" 每年10月20号1点10分30秒触发任务
"30 10 1 20 10 ? 2011" 2011年10月20号1点10分30秒触发任务
"30 10 1 ? 10 * 2011" 2011年10月每天1点10分30秒触发任务
"30 10 1 ? 10 SUN 2011" 2011年10月每周日1点10分30秒触发任务
"15,30,45 * * * * ?" 每15秒,30秒,45秒时触发任务
"15-45 * * * * ?" 15到45秒内,每秒都触发任务
"15/5 * * * * ?" 每分钟的每15秒开始触发,每隔5秒触发一次
"15-30/5 * * * * ?" 每分钟的15秒到30秒之间开始触发,每隔5秒触发一次
"0 0/3 * * * ?" 每小时的第0分0秒开始,每三分钟触发一次
"0 15 10 ? * MON-FRI" 星期一到星期五的10点15分0秒触发任务
"0 15 10 L * ?" 每个月最后一天的10点15分0秒触发任务
"0 15 10 LW * ?" 每个月最后一个工作日的10点15分0秒触发任务
"0 15 10 ? * 5L" 每个月最后一个星期四的10点15分0秒触发任务
"0 15 10 ? * 5#3" 每个月第三周的星期四的10点15分0秒触发任务




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值