在这里我用的版本是spring3.1.1和quartz2.1.1,。原来用的是spring3.0,但是每次quartz启动之后都是跑第一次 或者第二次定时任务之后job的状态就变成ERROR了,然后定时任务就一直跑不了了。后来把spring升为3.1.1后问题就好了。
下面开始说实现的步骤吧
首先 要先在项目中导入相关的jar包。
这里我就不多说了,可以到官网上去下载,
spring:http://www.springsource.org/
quartz:http://www.quartz-scheduler.org/
其次 ,因为需要把quartz的数据保存到数据库,所以要建立相关的数据库
这个可以从下载到的quartz包里面找到对应的sql脚本,目前可以支持mysql,DB2,oracle等主流的数据库,自己可以根据项目需要选择合适的脚本运行。
我的项目是mysql的,就在数据中建立了一个quartz的database,然后执行tables_mysql_innodb.sql脚本建表。
表建立好后可以看到相关的table
+————————–+ | Tables_in_quartz | +————————–+ | QRTZ_BLOB_TRIGGERS | | QRTZ_CALENDARS | | QRTZ_CRON_TRIGGERS | | QRTZ_FIRED_TRIGGERS | | QRTZ_JOB_DETAILS | | QRTZ_LOCKS | | QRTZ_PAUSED_TRIGGER_GRPS | | QRTZ_SCHEDULER_STATE | | QRTZ_SIMPLE_TRIGGERS | | QRTZ_SIMPROP_TRIGGERS | | QRTZ_TRIGGERS | +————————–+
然后 ,需要在项目中加上对应的配置。
首先是quartz的配置
quartz.properties
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
org.quartz.jobStore.misfireThreshold = 60000
#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
#org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.HSQLDBDelegate
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.scheduler.classLoadHelper.class=org.quartz.simpl.CascadingClassLoadHelper
#org.quartz.jobStore.useProperties = true
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = false
org.quartz.jobStore.maxMisfiresToHandleAtATime=1
其中org.quartz.jobStore.class是指明quartz的持久化用数据库来保存,
而org.quartz.jobStore.driverDelegateClass是根据选择的数据库类型不同而不同,我这里的是mysql,所以是org.quartz.impl.jdbcjobstore.StdJDBCDelegate
至于quartz.properties的其他详细说明可以看quartz.properties配置文件说明
数据库的相关配置
jdbc.properties
############quartz db########################
quartz.driverClassName=com.mysql.jdbc.Driver
quartz.url=jdbc:mysql://127.0.0.1:3306/quartz?useUnicode=true
quartz.username=username
quartz.password=password
quartz.minPoolSize=7
quartz.initialPoolSize=12
当然quartz的数据库相关配置也可以写在spring的配置中。
spring的相关配置
加上以下内容:
<bean id=”quartzDataSource” destroy-method=”close”> <property name=”driverClass” value=”${quartz.driverClassName}”/> <property name=”jdbcUrl” value=”${quartz.url}”/> <property name=”user” value=”${quartz.username}”/> <property name=”password” value=”${quartz.password}”/> <property name=”minPoolSize” value=”${quartz.minPoolSize}”/> <property name=”initialPoolSize” value=”${quartz.initialPoolSize}”/> </bean> <context:property-placeholder location=”classpath:jdbc.properties”/> <bean name=”quartzScheduler” class=”org.springframework.scheduling.quartz.SchedulerFactoryBean”> <property name=”dataSource”> <ref bean=”quartzDataSource” /> </property> <property name=”applicationContextSchedulerContextKey” value=”applicationContext” /> <property name=”configLocation” value=”classpath:quartz.properties”/> </bean>
接下来是java代码部分
首先加上一个定时任务类,继承org.quartz.Job
ParseModelJob
package com.iqbon.jcms.service.quartz;
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import com.iqbon.jcms.domain.Quartz;
import com.iqbon.jcms.util.BeanFactory;
public class ParseModelJob implements Job {
private static final Logger logger = Logger.getLogger(ParseModelJob.class);
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//这里输入任务处理的内容
}
}
}
然后增加一个用于查询当前定时任务信息的类。 QuartzDAO
package com.iqbon.jcms.dao.system;
import java.util.HashMap;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;
import com.iqbon.jcms.domain.Quartz;
import com.iqbon.jcms.domain.mapRow.QuartzMapper;
/**
* 定时任务的DAO
* @author iqbon
*
*/
@Repository
public class QuartzDAO {
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@Autowired
public void setDataSource(@Qualifier(“quartzDataSource”)
DataSource quartzDataSource) {//这里注明是配置文件里面的quartzDataSource数据源
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(quartzDataSource);
}
/**
* 查找所有的定时任务
* @return
*/
public List<Quartz> selectAllQuartJob() {
String sql = “select QRTZ_JOB_DETAILS.JOB_NAME,QRTZ_TRIGGERS.TRIGGER_NAME”
+ “,NEXT_FIRE_TIME,PREV_FIRE_TIME,TRIGGER_STATE,TRIGGER_TYPE,START_TIME,END_TIME”
+ “,QRTZ_JOB_DETAILS.DESCRIPTION from QRTZ_TRIGGERS inner join QRTZ_JOB_DETAILS ”
+ ” on QRTZ_TRIGGERS.JOB_NAME = QRTZ_JOB_DETAILS.JOB_NAME order by start_time”;
return namedParameterJdbcTemplate.query(sql, new HashMap<String, String>(), new QuartzMapper());
}
}
最后加上一个定时任务的服务类 QuartzService
package com.iqbon.jcms.service.quartz;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.iqbon.jcms.dao.system.QuartzDAO;
import com.iqbon.jcms.domain.Quartz;
@Service
public class QuartzService {
private static final Logger logger = Logger.getLogger(QuartzService.class);
private static Map<String, String> quartzStatus = new HashMap<String, String>(10);
@Autowired
private QuartzDAO quartzDAO;
@Autowired
private Scheduler quartzScheduler;
/**
* 查询所有定时任务信息
* @return
*/
public List<Quartz> getQuartzJobList() {
return quartzDAO.selectAllQuartJob();
}
/**
* 增加模板解析任务
* @param jobName
* @param topicIds
* @param description
* @param minutePattern
* @param hourPattern
* @throws SchedulerException
*/
public void addParseModelJob(String jobName, List<String> topicIds, String description,
String minutePattern, String hourPattern) throws SchedulerException {
//初始化JobDetail
JobDataMap dataMap = new JobDataMap();
dataMap.put(Quartz.PARSE_MODEL_TOPIC_KEY, topicIds);
dataMap.put(Quartz.JOB_LOG_KEY, new StringBuilder());
dataMap.put(Quartz.CREATE_JOB_TIME_KEY, DateFormatUtils.ISO_DATETIME_FORMAT.format(new Date()));
JobDetail jobDetail = JobBuilder.newJob(ParseModelJob.class)
.withIdentity(jobName, Scheduler.DEFAULT_GROUP).withDescription(description)
.usingJobData(dataMap).build();
// JobDetailBean jobDetail = new JobDetailBean();
//初始化CronTrigger
String cronPattern = “0 ” + minutePattern + ” ” + hourPattern + ” * * ?”;
CronTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity(jobName + “_trigger”, Scheduler.DEFAULT_GROUP)
.forJob(jobDetail).withSchedule(CronScheduleBuilder.cronSchedule(cronPattern)).build();
//添加cornjob
quartzScheduler.scheduleJob(jobDetail, trigger);
}
/**
* 删除定时任务
* @param jobName
* @throws SchedulerException
*/
public void deleteJob(String jobName) throws SchedulerException {
quartzScheduler.deleteJob(new JobKey(jobName, Scheduler.DEFAULT_GROUP));
}
}