在这里我用的版本是spring3.1.1和quartz2.1.1,。原来用的是spring3.0,但是每次quartz启动之后都是跑第一次 或者第二次定时任务之后job的状态就变成ERROR了,然后定时任务就一直跑不了了。后来把spring升为3.1.1后问题就好了。
下面开始说实现的步骤吧
这里我就不多说了,可以到官网上去下载,
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.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的配置中。
加上以下内容:
<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)); } }