现象:
系统通过配置添加或修改定时任务,每次添加或修改执行时间的时候都会调用下面代码块中的addJob方法,以致每次都创建StdSchedulerFactory对象;总会出现定时任务不执行的问题,是否和这种机制有关?
public static Scheduler getScheduler() throws SchedulerException {
Properties props = new Properties();
props.put(StdSchedulerFactory.PROP_THREAD_POOL_CLASS,"org.quartz.simpl.SimpleThreadPool");
props.put("org.quartz.threadPool.threadCount", "90");
sf = new StdSchedulerFactory(props);
return sf.getScheduler();
}
/**
* 添加一个定时任务
*
* @param jobId 任务名
* @param job 任务
* @param cronExpression trigger设置表达式
* @param jobDataMap job的参数
* @throws SchedulerException
* @throws ParseException
*/
public static void addJob(String jobId, Job job, String cronExpression, String methodName, List<String[]> logInfoList)
throws ParseException, SchedulerException {
String jobName = generateJobName(jobId);
Scheduler scheduler = getScheduler();
//新增job
JobDetail jobDetail = JobBuilder
.newJob(job.getClass())
.withIdentity(jobName, JOB_GROUP_NAME)
.storeDurably()
.build(); //任务名,任务组,任务执行类
scheduler.addJob(jobDetail,true);
System.out.println("-------------------------------------------------------------------------------scheduler.addJob(jobDetail,true); 执行完毕");
logger.info("新增定时任务"+jobName);
//新增触发器
String[] cronExps = StringUtils.splitByWholeSeparator(cronExpression,SEPARATOR);
for(int i=0;i<cronExps.length;i++){
try{
String triggerId = TRIGGER_NAME+jobId+"_"+generateSystime();
CronTrigger trigger = TriggerBuilder
.newTrigger()
.withIdentity(triggerId, TRIGGER_GROUP_NAME).forJob(jobName, JOB_GROUP_NAME)
.withSchedule(CronScheduleBuilder.cronSchedule(cronExps[i]).withMisfireHandlingInstructionFireAndProceed())
.build();
if(logInfoList != null) {
logInfoList.add(new String[]{triggerId, jobName, cronExpression, methodName});
}else {
LoggerUtils.quartzInitLoggerJob(triggerId, jobName, cronExpression, methodName);
}
scheduler.scheduleJob(trigger);
if(!scheduler.isShutdown()) {
scheduler.start();
System.out.println("-------------------------------------------------------------------------------scheduler.start(); 执行完毕");
}
logger.info("新增定时任务触发器"+trigger.getKey().getName());
}catch (SchedulerException ex){
logger.info(ex.getMessage());
System.out.println(ex.getMessage());
continue;
}
}
}
工厂类可以定义为静态变量,每次使用前检查一下,没有就创建,有就使用。但现在一般都是通过注解或者配置实现了,参考:
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!-- 更新考试状态 -->
<bean id="GetLievCourseStateScheduleExecute" class="com.schedule.GetLievCourseStateScheduleExecute" >
<property name="baseDAO" ref="baseDAO"></property>
</bean>
<!--更新考试状态 -->
<bean id="getLiveCourseStateScheduleExecute-methodInvokingJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="name" value="GetLievCourseStateScheduleExecute_Name"></property>
<property name="targetObject"><ref bean="GetLievCourseStateScheduleExecute"/></property>
<property name="targetMethod"><value>execute</value></property>
<property name="concurrent" value="false" />
</bean>
<!-- 更新考试状态 -->
<bean id="courseStateScheduleExecute-cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="getLiveCourseStateScheduleExecute-methodInvokingJobDetail"/>
</property>
<property name="cronExpression">
<!-- 更新考试状态,每5分钟触发一次 -->
<value>0 0/5 * * * ?</value>
</property>
</bean>
<bean id="stdScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<!-- 更新考试状态,每5分钟触发一次 -->
<ref bean="courseStateScheduleExecute-cronTrigger"/>
</list>
</property>
</bean>
</beans>