项目中经常需要计划任务来定时处理一些事情,Quartz是javaEE项目最常见的计划任务组件,Quartz本身支持集群,和spring结合很容易实现计划任务的配置,但是默认spring的Quartz配置
org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
并不支持集群模,当项目集群化部署的时候,项目中的计划任务有些事不能重复执行的,所以需要把job调度器换为
org.springframework.scheduling.quartz.JobDetailFactoryBean
并重写其中的jobClass。
重写的类:KuanrfQuartzJob.java
package com.kuanrf.common.util;
import java.lang.reflect.Method;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;
/**
* 重写QuartzJob
*
* 采用反射回调实际的计划任务处理方法
*
* @author lujun.chen
* @version [版本号, 2015年12月14日]
* @see [相关类/方法]
* @since [产品/模块版本]
*/
@DisallowConcurrentExecution
public class KuanrfQuartzJob extends QuartzJobBean {
// 计划任务所在类
private String targetObject;
// 具体需要执行的计划任务
private String targetMethod;
private ApplicationContext ctx;
@Override
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
try {
Object otargetObject = ctx.getBean(targetObject);
Method m = null;
try {
m = otargetObject.getClass().getMethod(targetMethod);
m.invoke(otargetObject);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
} catch (Exception e) {
throw new JobExecutionException(e);
}
}
public void setApplicationContext(ApplicationContext applicationContext) {
this.ctx = applicationContext;
}
public void setTargetObject(String targetObject) {
this.targetObject = targetObject;
}
public void setTargetMethod(String targetMethod) {
this.targetMethod = targetMethod;
}
}
spring配置:application_spring_trigger.xml
targetObject:定义计划任务的类
targetMethod:具体计划任务(方法名)
<bean id="gsTrigger" class="com.kuanrf.gs.trigger.Trigger"/>
<bean id="autoOrderAppraiseStateJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="durability" value="true" />
<property name="requestsRecovery" value="true" />
<property name="jobClass" value="com.kuanrf.common.util.KuanrfQuartzJob"/>
<property name="jobDataAsMap">
<map>
<entry key="targetObject" value="gsTrigger" />
<entry key="targetMethod" value="autoOrderAppraiseState" />
</map>
</property>
</bean>
<bean id="autoOrderAppraiseStateTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="autoOrderAppraiseStateJob"></property>
<property name="cronExpression">
<value> 0 * * * * ? </value>
</property>
</bean>
<bean id="KuanrfGSScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="applicationContextSchedulerContextKey" value="applicationContext" />
<property name="configLocation" value="classpath:config/quartz.properties" />
<property name="overwriteExistingJobs" value="true" />
<property name="startupDelay" value="30" />
<property name="autoStartup" value="true" />
<property name="triggers">
<list>
<ref bean=" autoOrderAppraiseStateTrigger "/>
</list>
</property>
</bean>
Quartz配置文件:quartz.properties
#==============================================================
#Configure Main Scheduler Properties
#==============================================================
org.quartz.scheduler.instanceName = KuanrfGSQuartzScheduler
org.quartz.scheduler.instanceId = AUTO
#==============================================================
#Configure JobStore
#==============================================================
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.maxMisfiresToHandleAtATime = 1
org.quartz.jobStore.misfireThreshold = 120000
org.quartz.jobStore.txIsolationLevelSerializable = true
#==============================================================
#Configure DataSource
#==============================================================
org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://127.0.0.1:3306/quartz?useUnicode=true&characterEncoding=UTF-8
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password = 123456
org.quartz.dataSource.myDS.maxConnections = 30
org.quartz.jobStore.selectWithLockSQL = SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE
#==============================================================
#Configure ThreadPool
#==============================================================
org.quartz.threadPool.class= org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount= 10
org.quartz.threadPool.threadPriority= 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread= true
#==============================================================
#Skip Check Update
#update:true
#not update:false
#==============================================================
org.quartz.scheduler.skipUpdateCheck = true
#============================================================================
# Configure Plugins
#============================================================================
org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingJobHistoryPlugin
org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownhook.cleanShutdown = true
参考文献: