- 浏览: 1594499 次
- 性别:
文章分类
- 全部博客 (2929)
- 非技术 (18)
- Eclipse (11)
- JAVA (31)
- 正则表达式 (0)
- J2EE (4)
- DOS命令 (2)
- WEB前端 (52)
- JavaScript (69)
- 数据库 (8)
- 设计模式 (0)
- JFreechart (1)
- 操作系统 (1)
- 互联网 (10)
- EasyMock (1)
- jQuery (5)
- Struts2 (12)
- Spring (24)
- 浏览器 (16)
- OGNL (1)
- WebService (12)
- OSGi (14)
- 软件 (10)
- Tomcat (2)
- Ext (3)
- SiteMesh (2)
- 开源软件 (2)
- Hibernate (2)
- Quartz (6)
- iBatis (2)
最新评论
一.名词简介:
Quartz是一个完全由java编写的开源作业调度框架。Spring
为创建Quartz的Scheduler、Trigger和JobDetail提供了便利的FactoryBean类,以便能够在 Spring
容器中享受注入的好处。此外Spring还提供了一些便利工具类直接将Spring中的Bean包装成合法的任务。Spring进一步降低了使用
Quartz的难度,能以更具Spring风格的方式使用Quartz。概括来说它提供了两方面的支持:
1)为Quartz的重要组件类提供更具Bean风格的扩展类;
2)提供创建Scheduler的BeanFactory类,方便在Spring环境下创建对应的组件对象,并结合Spring容器生命周期进行启动和停止的动作。
二。项目实践
情景一:集群部署,持久化,动态创建schedule配置
1.spring-schedule.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<bean id="GMTZone" class="java.util.TimeZone" factory-method="getTimeZone">
<constructor-arg value="GMT"/>
</bean>
<!--业务job生成工厂,该工厂注入了scheduleManager -->
<bean id="pharmaskyJobFactory
" class="com.infowarelab.pharmasky.service.schedule.PharmaskyJobFactory
"/>
<!--schedule管理器,用于动态添加,修改,删除schedule -->
<bean id="scheduleManager" class="com.infowarelab.pharmasky.service.schedule.ScheduleManager">
<property name="scheduler" ref="scheduleFactoryBean"/>
</bean>
<!--持久化,集群schedule工厂配置信息,实际可以在classpath下附加quartz.properties定义这些属性值 -->
<bean id="scheduleFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceName">PharmaskyClusteredScheduler</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
<prop key="org.quartz.threadPool.threadCount">25</prop>
<prop key="org.quartz.threadPool.threadPriority">5</prop>
<prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop
key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
<prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.jobStore.clusterCheckinInterval">20000</prop>
</props>
</property>
<property name="triggers">
<list>
<ref local="orderConversionCronTrigger"/>
</list>
</property>
</bean>
<!--固定jobDetail, org.quartz.JobDetail类型的JobDetail必须实现指定接口方法来执行job-->
<bean id="autoOrderStatusConversionJob" class="org.quartz.JobDetail
">
<property name="jobClass">
<value>com.infowarelab.pharmasky.service.schedule.job.HisAutoOrderConversionJob</value>
</property>
<property name="name" value="PMS-SYS-JOB-HIS-ORDER-CONVERSION"/>
<property name="group" value="PMS-GROUP"/>
<property name="requestsRecovery" value="true"/>
</bean>
<!--job触发器,绑定上面的jobDetail -->
<bean id="orderConversionCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="beanName" value="PMS-SYS-JOB-HIS-ORDER-CONVERSION-Trigger"/>
<property name="jobDetail" ref="autoOrderStatusConversionJob" />
<property name="cronExpression" value="0 0/20 * * * ?" />
<property name="timeZone" ref="GMTZone"/>
</bean>
</beans>
2.ScheduleManager.java动态管理schedule工具类
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->package com.infowarelab.pharmasky.service.schedule;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import com.infowarelab.common.log.Log;
import com.infowarelab.common.log.LogFactory;
import com.infowarelab.pharmasky.util.Config;
public class ScheduleManager {
private static final Loglog = LogFactory.getLog(ScheduleManager. class );
private Schedulerscheduler;
public void start() throws SchedulerException {
if (scheduler == null ) {
scheduler = getScheduler();
}
if (scheduler.isShutdown() || scheduler.isInStandbyMode()) {
scheduler.start();
}
}
public void pause() throws SchedulerException {
if (scheduler == null ) {
scheduler = getScheduler();
}
if (scheduler.isStarted()) {
scheduler.standby();
}
}
public void stop() throws SchedulerException {
if (scheduler == null ) {
scheduler = getScheduler();
}
if (scheduler.isStarted() || scheduler.isInStandbyMode()) {
scheduler.shutdown();
}
}
public ListlistJobDetails() throws SchedulerException {
ListrstList = new ArrayList < JobDetail > ();
if (scheduler == null ) {
scheduler = getScheduler();
}
String[]groupNames = scheduler.getJobGroupNames();
log.info( " [INFO]thegroupsincurrentscheduleris: "
+ groupNames.length);
for ( int i = 0 ;i < groupNames.length;i ++ ) {
String[]jobNames = scheduler.getJobNames(groupNames[i]);
for ( int j = 0 ;j < jobNames.length;j ++ ) {
JobDetailjobDetail = scheduler.getJobDetail(jobNames[j],
groupNames[i]);
if (jobDetail != null ) {
rstList.add(jobDetail);
}
}
}
return rstList;
}
public JobDetailgetJobDetail(StringjobName,StringjobGroupName)
throws SchedulerException {
if (scheduler == null ) {
scheduler = getScheduler();
}
JobDetailjob = scheduler.getJobDetail(jobName,jobGroupName);
if (job == null ) {
log.info( " [INFO]noneobjectrelativethejobName: " + jobName
+ " andjobGroupName: " + jobGroupName);
}
return job;
}
public List < JobDetail > getJobDetailByGroup(StringjobGroupName)
throws SchedulerException {
List < JobDetail > list = new ArrayList < JobDetail > ();
if (scheduler == null ) {
scheduler = getScheduler();
}
String[]jobNames = scheduler.getJobNames(jobGroupName);
log.debug( " [DEBUG]jobNameswith/ "" +jobGroupName
+ " / " asgroupName: " +jobNames);
for ( int i = 0 ;i < jobNames.length;i ++ ) {
JobDetailjobDetail = getJobDetail(jobNames[i],jobGroupName);
if (jobDetail != null ) {
list.add(jobDetail);
} else {
log
.debug( " [DEBUG]JobDetailwith{/ ""
+ jobNames[i]
+ " / " ,/ ""
+ jobGroupName
+ " / " } asthejobNameandjobGroupNamecannotbefound ! " );
}
}
return list;
}
public boolean addJobDetail(JobDetailjobDetail,StringcronExpress)
throws SchedulerException,ParseException {
if (scheduler == null ) {
scheduler = getScheduler();
}
if (jobDetail != null && cronExpress != null ) {
Triggertrigger = new CronTrigger(jobDetail.getName(),jobDetail.getGroup(),
jobDetail.getName(),jobDetail.getGroup(),cronExpress);
DatejobDate = scheduler.scheduleJob(jobDetail,trigger);
log
.info( " [INFO]jobDetail: "
+ jobDetail.getFullName()
+ " hasbeenaddedintothescheduler,andthefirstFiredTimeis: "
+ jobDate);
return (jobDate == null ) ? false : true ;
} else {
log
.info( " [INFO]addjobDetailfailure,theparametersonjobDetailortriggerhasnullvalue! " );
}
return false ;
}
public Trigger[]getJobTrigger(StringjobName,StringjobGroupName)
throws SchedulerException {
if (scheduler == null ) {
scheduler = getScheduler();
}
return scheduler.getTriggersOfJob(jobName,jobGroupName);
}
public List < Trigger > listTrigger() throws SchedulerException {
List < Trigger > triggerList = new ArrayList < Trigger > ();
if (scheduler == null ) {
scheduler = getScheduler();
}
String[]triggerGroupNames = scheduler.getTriggerGroupNames();
log
.info( " [INFO]thetriggergroupsamountswhichisregistedwithinthesystemis: "
+ triggerGroupNames.length);
for (StringtriggerGroupName:triggerGroupNames) {
if (triggerGroupName != null ) {
String[]triggerNames = scheduler
.getTriggerNames(triggerGroupName);
for (StringtriggerName:triggerNames) {
Triggertrigger = scheduler.getTrigger(triggerName,
triggerGroupName);
if (trigger != null
&& scheduler.getTriggerState(triggerName,
triggerGroupName) == Trigger.STATE_NORMAL) {
triggerList.add(trigger);
} else {
log.info( " [INFO]thetrigger: "
+ ((trigger == null ) ? trigger.getFullName()
: " null " ) + " ,notexists "
+ " orhasthenotnormalstatus " );
}
}
}
}
return triggerList;
}
public boolean reScheduleJob(StringjobName,StringjobGroupName,
StringcomputedStr) throws SchedulerException,ParseException {
if (scheduler == null ) {
scheduler = getScheduler();
}
TriggernewTrigger = new CronTrigger(jobName,jobGroupName,jobName,
jobGroupName,computedStr);
newTrigger.setJobName(jobName);
newTrigger.setJobGroup(jobGroupName);
DatetriggerDate = scheduler.rescheduleJob(jobName,jobGroupName,newTrigger);
log.info( " [INFO]thejob " + jobName
+ " hasbeenupdatetofiredon: " + triggerDate);
return (triggerDate == null ) ? false : true ;
}
public StringgenScheduleTimeStr( byte type,Short scheduleTimeParams) {
Stringpattern = null ; // variableforcronexpress
switch (type) {
case 1 :
// autoordercreationjob,theparameterturnis:weekInterval,
// weekday,hour,minute
// "0minutehour?*weekDay/weekInterval"
pattern = Config
.getString( " schedule.cron.express.his.order.creation " );
log.info( " [INFO]partternforhisordercreationcronexpress: "
+ pattern);
for ( int i = 0 ;i < scheduleTimeParams.length;i ++ ) {
switch (i) {
case 0 : // minute
pattern = StringUtils.replace(pattern, " minute " ,
scheduleTimeParams[ 0 ].toString());
break ;
case 1 : // hour
pattern = StringUtils.replace(pattern, " hour " ,
scheduleTimeParams[ 1 ].toString());
break ;
case 2 : // weekDay
pattern = StringUtils.replace(pattern, " weekDay " ,
getWeekIdentify(scheduleTimeParams[ 2 ]));
break ;
case 3 : // weekInterval
pattern = StringUtils.replace(pattern, " weekInterval " ,
scheduleTimeParams[ 3 ].toString());
break ;
default :
break ;
}
}
break ;
case 2 :
// hisstocksyncjob,theparameterturnis:dayInterval,hour,
// minute
// "0minutehour*/dayInterval*?"
pattern = Config.getString( " schedule.cron.express.his.stock.sync " );
log.info( " [INFO]partternforhisordercreationcronexpress: "
+ pattern);
for ( int i = 0 ;i < scheduleTimeParams.length;i ++ ) {
switch (i) {
case 0 : // minute
pattern = StringUtils.replace(pattern, " minute " ,
scheduleTimeParams[ 0 ].toString());
break ;
case 1 : // hour
pattern = StringUtils.replace(pattern, " hour " ,
scheduleTimeParams[ 1 ].toString());
break ;
case 2 : // dayInterval
pattern = StringUtils.replace(pattern, " dayInterval " ,
scheduleTimeParams[ 2 ].toString());
break ;
default :
break ;
}
}
break ;
default :
break ;
}
log.info( " [INFO]schedulejobcronexpressis: " + pattern);
return (pattern == null ) ? null :pattern.trim();
}
/***/ /** ********************************************************************** */
/***/ /** helpermethodorgettersandsetters* */
/***/ /** ********************************************************************** */
/***/ /**
*gettheweekday'sidentifylike"SUN","MON"andsoon.Inthismethod
*thedata"1"equals"SUN",sothe"7"equals"SAT";
*
* @param short
*thenumericdataforweekday
* @return Stringtheweekdayidentifywithcorrectnumericdata
*/
private StringgetWeekIdentify( short weekDay) {
Stringvalue = null ;
switch (weekDay) {
case 1 :
value = " SUN " ;
break ;
case 2 :
value = " MON " ;
break ;
case 3 :
value = " TUE " ;
break ;
case 4 :
value = " WED " ;
break ;
case 5 :
value = " THU " ;
break ;
case 6 :
value = " FRI " ;
break ;
case 7 :
value = " SAT " ;
break ;
default :
break ;
}
return value;
}
public SchedulergetScheduler() {
return scheduler;
}
public void setScheduler(Schedulerscheduler) {
this .scheduler = scheduler;
}
}
情景二:单机部署,固定触发规则多个schedule,不用持久化
1.spring-schedule.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<!-- Job Bean -->
<bean name="autoOrderAuditService" class="com.infowarelab.sam.service.job.AutoOrderAuditService"></bean>
<bean name="sendAuditedOrderService" class="com.infowarelab.sam.service.job.SendAuditedOrderService"></bean>
<!-- Job由于以上job bean具有相同的触发规则,所以统一集中在这个管理器执行-->
<bean id="timerJobManagerJob" class="com.infowarelab.sam.service.job.SamJobManager" autowire="no">
<property name="tasks">
<list>
<ref bean="autoOrderAuditService"/>
<ref bean="sendAuditedOrderService"/>
</list>
</property>
<property name="samBaseInfoService" ref="samBaseInfoService"></property>
</bean>
<bean id="timerJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
" autowire="no">
<property name="targetObject" ref="timerJobManagerJob" />
<property name="targetMethod" value="jobExpires" />
</bean>
<bean id="timerCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" autowire="no">
<property name="jobDetail" ref="timerJobDetail" />
<property name="cronExpression">
<value>0 0/15 * * * ?</value>
</property>
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean" autowire="no">
<property name="triggers">
<list>
<ref bean="timerCronTrigger" />
</list>
</property>
</bean>
</beans>
参考资料:
cronExpression表达式:
http://hi.baidu.com/the_space_of_programmer/blog/item/725759f78d383e27720eec80.html (cronExpression
quartz介绍:
http://hi.baidu.com/alliance_alex/blog/item/5c998d64241173f2f73654b0.html
集群及quartz配置说明:
http://hi.baidu.com/jiangyou001/blog/item/5196d990862d5789a977a4af.html
http://gocom.primeton.com/modules/newbb/forumtopic19180_9963_40.htm
发表评论
-
spring2.0和spring2.5及以上版本的jar包区别 spring jar 包详解
2009-07-22 15:07 809spring jar 包详解 spr ... -
spring2.0升级到spring2.5
2009-07-22 15:09 822在spring2.0升级到spring2. ... -
spring2.5新特性(转)
2009-07-22 15:10 679简介 从诞生之初,Spring框架就坚守它的宗旨:简化企 ... -
Spring中使用FreeMaker或Vilocity模板发送邮件
2009-07-22 16:38 873本文以用户注册后为用户发送一封邮件为例子,讲述如何在Sprin ... -
Quartz与Spring的集成【转】
2009-08-05 15:21 7952.1 Scheduler 总入口 <bean n ... -
Quartz在Spring中动态设置cronExpression研究(spring设置动态定时任务)【转】
2009-08-05 15:49 848什么是动态定时任务:是由客户制定生成的,服务端只知道该 ... -
Spring结合Quartz实现多任务定时调用
2009-08-05 15:51 749Quartz框架提供了丰富的任务调度支持,比如 ... -
在Spring中使用Quartz进行任务调度
2009-08-06 10:30 851概述 各种企业应用几乎都会碰到任务调度的需求,就拿论坛 ... -
任务调度开源框架Quartz
2009-08-06 12:21 742概述 各种企业应用几 ... -
Spring的transactionAttributes
2009-08-11 11:42 602PROPAGATION_REQUIRED--支持当前事务, ... -
Spring配置中transactionAttributes的意义
2009-08-11 11:43 814最近使用JSF+Spring+OpenJPA ... -
详解spring事务属性
2009-08-11 11:45 651Spring声明式事务让我们从复杂的事务处理中得到解脱。使得我 ... -
acegi参考的部分翻译
2009-08-20 15:34 640序 1. 安全 1.1 准备 1 ... -
Acegi Security -- Spring下最优秀的安全系统
2009-08-20 15:40 797一Acegi安全系统介绍 Author: cac 差沙 ... -
【SSI开发总结.1】struts2整合spring
2009-08-20 15:48 669在Struts2中整合Spring的IoC支持是一件十分简单的 ... -
【SSI开发总结.4】Spring中使用Acegi安全框架
2009-08-20 15:49 682Acegi认证授权主要基于 ... -
【SSI开发总结.3】基于ibatis的自定义分页
2009-08-20 15:49 790分页,在web应用程序中非常常见的功能,也是最基本的功能, ... -
【SSI开发总结.7】Struts+Spring+Ibatis环境配置(二)
2009-08-20 15:50 602spring提供了ibatis的模板类封装,通过简单的设置就能 ... -
【SSI开发总结.6】Struts+Spring+Ibatis环境配置(一)
2009-08-20 15:50 751为了使struts2和spring集成,必须下载一个 ... -
Spring 配置多个数据源
2009-08-20 16:05 700<?xml version="1.0&qu ...
相关推荐
spring的jar包及quartz的jar包,需求的下
关于spring中quartz的配置
本项目来源与网络,本人对项目...直接通过mvn 倒入项目,在Spring-quartz-demo\src\main\webapp\sql 有sql 建立数据库,表 启动tomcat 直接访问http://localhost:8080/Spring-quartz-demo/task/taskList.htm 就可以使用
spring+quartz demo,下载后即可运行,很强大哦....
Java_Spring与Quartz的整合
spring的quartz使用实例,spring的quartz使用实例
spring整合quartz文档
spring注解Quartz定时执行功能
spring整合quartz使用jdbc存储任务,并配置为quartz集群应用
Spring_QuartZDemo
所需jar如下: spring-beans-3.2.4.RELEASE.jar spring-core-3.2.4.RELEASE.jar spring-expression-3.2.4.RELEASE....quartz-all-2.1.7.jar spring-tx-3.2.4.RELEASE.jar slf4j-log4j12-1.6.1.jar slf4j-api-1.6.1.jar
spring 集成quartz定时任务 用数据库实现quartz的集群
自己写的demo项目 ,可以直接运行,目前定时了一个任务。
spring集成quartz使用需要的jar包下载。
spring-quartz的标准配置文件
spring-quartz简单实例 简单的quartz定时任务实例代码
Spring+quartz相关jar包.rar
spring+quartz定时小例子,架包+文档 我自己整理的
Quartz学习文档 Spring + Quartz配置详细实例 jar包 Quartz时间格式设置
Spring整合Quartz定时发送邮件