Spring3整合Quartz实现定时作业

时间:2021-12-27 07:52:00

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的日程序表。Jobs可以做成标准的Java组件或 EJBs。
Quartz是一个任务日程管理系统,一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。

Quartz用一个小Java库发布文件(.jar文件),这个库文件包含了所有Quartz核心功能。这些功能的主要接口(API)是Scheduler接口。它提供了简单的操作,例如:将任务纳入日程或者从日程中取消,开始/停止/暂停日程进度。

quartz下载: http://www.quartz-scheduler.org/download/index.html

Spring3中整合Quartz
虽然Quartz已经发布了2.X版本,但是Spring3目前只能整合Quartz1.8.5及以下版本。

项目结构图
Spring3整合Quartz实现定时作业

1.作业调度类的实现

package org.dennist.jobs;

import org.apache.log4j.Logger;
import org.dennist.service.SystemTimeHandler;
/**
*
*
*
* @version : 1.1
*
* @author : 苏若年 <a href="mailto:DennisIT@163.com">发送邮件</a>
*
* @since : 1.0 创建时间: 2013-7-8 上午09:49:20
*
* TODO : org.dennist.jobs.TimeQuartzJob.java
*
*/ public class TimeQuartzJob { private final Logger logger = Logger.getLogger(TimeQuartzJob.class); private SystemTimeHandler systemTimeHandler; public void noticeSystemTime(){
logger.info("定时器执行,调用系统时间服务类中的系统时间通知方法");
systemTimeHandler.noticeSystemTime();
} public SystemTimeHandler getSystemTimeHandler() {
return systemTimeHandler;
} public void setSystemTimeHandler(SystemTimeHandler systemTimeHandler) {
this.systemTimeHandler = systemTimeHandler;
} }

作业调度类中调用实现了SystemTimeHandler接口的类SystemTimeHandlerImpl,实现定时向控制台输出格式化的系统时间,SystemTimeHandlerImpl的类实现如下

package org.dennist.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date; import org.apache.log4j.Logger;
import org.dennist.jobs.TimeQuartzJob;
import org.dennist.service.SystemTimeHandler; /**
*
*
*
* @version : 1.1
*
* @author : 苏若年 <a href="mailto:DennisIT@163.com">发送邮件</a>
*
* @since : 1.0 创建时间: 2013-7-8 上午09:55:10
*
* TODO : org.dennist.service.impl.SystemTimeHandlerImpl.java
*
*/ public class SystemTimeHandlerImpl implements SystemTimeHandler{ private final Logger logger = Logger.getLogger(TimeQuartzJob.class); public void noticeSystemTime() {
logger.info("notice system time to all users");
SimpleDateFormat format = new SimpleDateFormat("现在时间是: yyyy/MM/dd hh:mm:ss");
System.out.println(format.format(new Date()).toString());
} }

2.Web.xml中配置spring上下文监听和quartz初始化监听

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name>spring-quartz</display-name>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>quartzapp</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>3000</param-value>
</context-param> <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-context.xml</param-value>
</context-param> <!-- Quartz初始化监听 -->
<listener>
<listener-class>org.quartz.ee.servlet.QuartzInitializerListener</listener-class>
</listener> <!-- 注入 字符编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

3.contextConfigLocation指定配置文件的路径为根目录下的spring-context.xml,该配置文件中引入系统Bean实例化管理配置文件spring-beans.xml和定时任务配置类spring-jobs.xml.

spring-context.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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <context:component-scan base-package="com.dennisit" /> <!-- Root Context: defines shared resources visible to all other web components --> <import resource="spring-beans.xml" /> <import resource="spring-jobs.xml" /> </beans>

Bean管理配置文件spring-beans.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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <!-- 实例化service对象 -->
<bean id="systemTimeHandler" class="org.dennist.service.impl.SystemTimeHandlerImpl" autowire="byType"/> </beans>

定时作业管理配置文件spring-jobs.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:p="http://www.springframework.org/schema/p"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <!--
这里加入了
xmlns:task="http://www.springframework.org/schema/task"
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd
--> <!-- spring3.0之前的用法,配置比较繁琐 --> <!-- 值班提醒定时器 这个是定时器要调用方法的类 -->
<bean id="timeNoticeJob" class="org.dennist.jobs.TimeQuartzJob" autowire="byType"/> <!-- 定义调用对象和调用对象的方法 -->
<bean id="timeNoticeJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="timeNoticeJob"/> <!-- 调用的类 -->
<property name="targetMethod" value="noticeSystemTime" /> <!-- 调用类中的方法 -->
<property name="concurrent" value="true"/> <!-- false,证明不执行并发任务 -->
</bean> <!-- 定义触发时间 -->
<bean id="timeNoticeJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="timeNoticeJobDetail" />
<property name="cronExpression">
<value>0 0/1 * * * ?</value> <!-- cron表达式 此处定义为一直触发执行任务 -->
</property>
</bean> <!-- 调度工厂,将触发时间列入; 如果将lazy-init='false'那么容器启动就会执行调度程序 -->
<bean id="schedulerlist" lazy-init="false"
autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="timeNoticeJobTrigger"/>
<!-- 可以增加多个定时作业 -->
</list>
</property>
</bean> </beans>

4.程序执行效果图,每隔一分钟在控制台打印系统时间

Spring3整合Quartz实现定时作业

说明:上面的方法是在Spring3之前用的配置方法,在spring3之后使用如下方法配置,方便简单.

<?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:p="http://www.springframework.org/schema/p"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <!-- spring3.0之后的新用法,配置有变化,而且比以前简单了很多 --> <!-- 定时器 这个是定时器要调用方法的类 -->
<bean id="timeNoticeJob" class="org.dennist.jobs.TimeQuartzJob" autowire="byType"/> <!-- 定义调用对象和调用对象的方法 -->
<task:scheduled-tasks>
<!-- 调用的类TimeQuartzJob 调用类中的方法noticeSystemTime 设置每分钟调用一次-->
<task:scheduled ref="timeNoticeJob" method="noticeSystemTime" cron="0 0/1 * * * ?" />
</task:scheduled-tasks> </beans>

5.Quartz中的cron表达式说明

一个cron表达式有至少6个(也可能是7个)由空格分隔的时间元素。从左至右,这些元素的定义如下:
1.秒(0–59)
2.分钟(0–59)
3.小时(0–23)
4.月份中的日期(1–31)
5.月份(1–12或JAN–DEC)
6.星期中的日期(1–7或SUN–SAT)
7.年份(1970–2099) 为可选属性

每一个元素都可以显式地规定一个值(如6),一个区间(如9-12),一个列表(如9,11,13)或一个通配符(如*)。“月份中的日期”和“星期中的日期”这两个元素是互斥的,因此应该通过设置一个问号(?)来表明你不想设置的那个字段。如下显示了一些cron表达式的例子和它们的意义:

"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触发
"0 6 * * *" 每天早上6点
"0 */2 * * *"每两个小时
"0 23-7/2,8 * * *" 晚上11点到早上8点之间每两个小时,早上八点
"0 11 4 * 1-3" 每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
"0 4 1 1 *" 1月1日早上4点

附 录:
Quartz中的cron表达式跟Linux中的crontab有所不同,如下为Linux中的自动化定时任务crontab命令
基本格式 :

*  *  *  *  *  command
分 时 日 月 周 命令

前五个字段可以取整数值,指定何时开始工作,第六个域是字符串,即命令字段,其中包括了crontab调度执行的命令。 各个字段之间用spaces或tabs分割。

前5个字段分别表示:
     分钟:0-59
     小时:1-23
     日期:1-31
     月份:1-12
     星期:0-6(0表示周日)
第6个字段表示运行的命令

还可以用一些特殊符号:

*:表示任何时刻
       ,:表示分割
     -:表示一个段,如第二端里: 1-5,就表示1到5点
     /n: 表示每个n的单位执行一次,如第二段里,*/1, 就表示每隔1个小时执行一次命令。也可以写成1-23/1.

举例:

30 21 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每晚的21:30重启apache。 45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每月1、10、22日的4 : 45重启apache。 10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每周六、周日的1 : 10重启apache。 0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。 0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每星期六的11 : 00 pm重启apache。 * */1 * * * /usr/local/etc/rc.d/lighttpd restart
每一小时重启apache * 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart
晚上11点到早上7点之间,每隔一小时重启apache 0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart
每月的4号与每周一到周三的11点重启apache 0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart
一月一号的4点重启apache

参考文献:[ http://blog.sina.com.cn/s/blog_71420de901019jg5.html ]

转载请注明出处:[ http://www.cnblogs.com/dennisit/p/3177800.html ]