Spring3整合Quartz实现定时作业
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及以下版本。
项目结构图
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之前用的配置方法,在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 ]