项目中经常需要计划任务来定时处理一些事情,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
参考文献:
http://blog.csdn.net/l1028386804/article/details/49150267