天天看點

Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)

摘要:在項目的管理功能中,對定時任務的管理有時會很常見。但一般定時任務配置都在xml中完成,包括cronExpression表達式,十分的友善。但是如果我的任務資訊是儲存在資料庫的,想要動态的初始化,還有就是任務較多的時候不是得有一大堆的xml配置?或者說我要修改一下trigger的表達式,使原來5秒運作一次的任務變成10秒運作一次,或者說我要控制定時任務的 “ 暫停 ” 呢?暫停之後又要在某個時間點 “ 重新開機 ” 該定時任務呢?或者說直接 “ 删除 ” 該定時任務呢?要 改變某定時任務的觸發時間呢?這時問題就來了,試過在配置檔案中不傳入cronExpression等參數,但是啟動時就報錯了,難道我每次都修改xml檔案然後重新開機應用嗎,這顯然不合适的。

最理想的是在與spring整合的同時又能實作動态任務的添加、删除及修改配置,而且不需要重新開機應用。

 首先我們來回顧一下spring中使用quartz的配置代碼:

<!-- 使用MethodInvokingJobDetailFactoryBean,任務類可以不實作Job接口,通過targetMethod指定調用方法-->
<bean id="taskJob" class="com.tyyd.dw.task.DataConversionTask"/>
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="group" value="job_work"/>
    <property name="name" value="job_work_name"/>
    <!--false表示等上一個任務執行完後再開啟新的任務-->
    <property name="concurrent" value="false"/>
    <property name="targetObject">
        <ref bean="taskJob"/>
    </property>
    <property name="targetMethod">
        <value>execute</value>
    </property>
</bean>
<!--  排程觸發器 -->
<bean id="myTrigger"
      class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <property name="name" value="work_default_name"/>
    <property name="group" value="work_default"/>
    <property name="jobDetail">
        <ref bean="jobDetail" />
    </property>
    <property name="cronExpression">
        <value>0/5 * * * * ?</value>
    </property>
</bean>
<!-- 排程工廠 -->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="myTrigger"/>
        </list>
    </property>
</bean>      

所有的配置都在xml中完成,包括cronExpression表達式,十分的友善。但是如果定時任務一多并且需要手動變化時,就得有一大堆的xml配置,不友善管理。

于是在設計時我想到以下幾點

1、減少spring的配置檔案。

2、使用者可以通過頁面等方式添加、啟用、禁用某個任務。

3、使用者可以修改某個已經在運作任務的運作時間表達式,即CronExpression。

4、為友善維護,簡化任務的運作調用處理,任務的運作入口即Job實作類最好隻有一個,該Job運作類相當于工廠類,在實際調用時把任務的相關資訊通過參數方式傳入,由該工廠類根據任務資訊來具體執行需要的操作。

就像如下圖所示:

1、可在頁面直接檢視任務詳情

Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)

2、可添加、修改

Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)

3、可立即執行,并檢視執行詳情

Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)

在上面的思路下來進行我們的開發吧。

一、初始化用的資料庫腳本

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for task_detail
-- ----------------------------
DROP TABLE IF EXISTS `task_detail`;
CREATE TABLE `task_detail` (
  `job_id` int(100) NOT NULL AUTO_INCREMENT,
  `job_name` varchar(200) DEFAULT NULL COMMENT '任務名稱',
  `job_group` varchar(100) DEFAULT NULL COMMENT '任務分組',
  `job_status` varchar(5) DEFAULT NULL COMMENT '任務狀态 0禁用 1啟用 2删除',
  `cron_expression` varchar(200) DEFAULT NULL COMMENT '任務運作時間表達式',
  `bean_class` varchar(300) DEFAULT NULL COMMENT '任務執行類',
  `execute_method` varchar(100) DEFAULT NULL COMMENT '任務執行方法',
  `create_time` date DEFAULT NULL COMMENT '任務建立時間',
  `update_time` date DEFAULT NULL COMMENT '任務更新時間',
  `job_desc` varchar(500) DEFAULT NULL COMMENT '任務描述',
  PRIMARY KEY (`job_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of task_detail
-- ----------------------------
INSERT INTO `task_detail` VALUES ('9', '測試手動設定任務', 'testQuartzTask', null, '0 0 1 * * ?', 'com.zealer.cps.task.executor.TestQuartzTask', 'printOneWord', '2017-06-22', '2017-06-22', '列印一句話');      

 然後建立對應的實體類ScheduleJob.java

Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)
Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)
1 package com.zealer.cps.task.value;
 2 
 3 /**
 4  * 定時任務封裝類
 5  * @author   xiaohe
 6  */
 7 public class ScheduleJob
 8 {
 9     /** 任務id */
10     private int jobId;
11     
12     /** 任務名稱 */
13     private String jobName;
14     
15     /** 任務分組 */
16     private String jobGroup;
17     
18     /** 任務狀态 0禁用 1啟用 2删除*/
19     private String jobStatus;
20     
21     /** 任務運作時間表達式 */
22     private String cronExpression;
23     
24     /** 任務執行類 */
25     private String beanClass;
26     
27     /** 任務執行方法 */
28     private String executeMethod;
29     
30     /** 任務建立時間 */
31     private String createTime;
32     
33     /** 任務更新時間 */
34     private String updateTime;
35     
36     /** 任務描述 */
37     private String jobDesc;
38    
39     //set與get方法這裡省略,大家可以自己生成
40     ......  
41 }      

View Code

二、spring配置檔案spring.xml

<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />      

然後在web.xml加入

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring.xml</param-value>
</context-param>      

三、編寫任務控制器TaskController.java

Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)
Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)
1 package com.zealer.cps.task.controller;
  2 
  3 import java.text.SimpleDateFormat;
  4 import java.util.Date;
  5 import java.util.HashMap;
  6 import java.util.Map;
  7 
  8 import javax.annotation.Resource;
  9 import javax.servlet.http.HttpServletRequest;
 10 
 11 import org.slf4j.Logger;
 12 import org.slf4j.LoggerFactory;
 13 import org.springframework.http.HttpStatus;
 14 import org.springframework.http.ResponseEntity;
 15 import org.springframework.stereotype.Controller;
 16 import org.springframework.ui.Model;
 17 import org.springframework.web.bind.annotation.ModelAttribute;
 18 import org.springframework.web.bind.annotation.RequestMapping;
 19 import org.springframework.web.bind.annotation.RequestMethod;
 20 import org.springframework.web.bind.annotation.RequestParam;
 21 import org.springframework.web.bind.annotation.ResponseBody;
 22 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 23 import com.zealer.cps.base.annotation.Log;
 24 import com.zealer.cps.base.constant.AppConstant;
 25 import com.zealer.cps.base.controller.BaseController;
 26 import com.zealer.cps.base.message.SuccessActionResult;
 27 import com.zealer.cps.base.model.vo.PaginationBean;
 28 import com.zealer.cps.base.util.HttpUtils;
 29 import com.zealer.cps.task.manage.JobMethod;
 30 import com.zealer.cps.task.service.QuartzJobService;
 31 import com.zealer.cps.task.value.ScheduleJob;
 32 import com.zealer.cps.task.value.ScheduleJobItem;
 33 import com.zealer.cps.task.value.ScheduleJobReq;
 34 
 35 @Controller
 36 @RequestMapping( "/taskController" )
 37 public class TaskController extends BaseController
 38 {
 39     private static Logger log = LoggerFactory.getLogger( TaskController.class );
 40 
 41     @Resource( name = "quartzJobService" )
 42     private QuartzJobService quartzJobService;
 43 
 44     @Resource( name = "JobMethod" )
 45     private JobMethod jobMethod;
 46 
 47     @RequestMapping( "/list" )
 48     @Log( "任務清單" )
 49     public String listJob( @ModelAttribute("job") ScheduleJobReq jobReq, Model model, HttpServletRequest request )
 50     {
 51         PaginationBean<ScheduleJob> pb = quartzJobService.getJobsByPage( jobReq );
 52         try {
 53             pb.setUrl( HttpUtils.getRequestInfo( request, true ) );
 54         } catch ( Exception e ) {
 55             log.error( "get request url error", e );
 56         }
 57         model.addAttribute( "pb", pb );
 58         return("task/taskList");
 59     }
 60 
 61 
 62     /**
 63      * 立即執行定時任務
 64      * @param job 任務實體
 65      * @param model
 66      * @return
 67      */
 68     @ResponseBody
 69     @RequestMapping( value = "/executeJob", produces = "application/json;charset=utf-8" )
 70     @Log( "立即執行任務" )
 71     public ResponseEntity<Map<String, Object> > executeJob( ScheduleJob job, Model model )
 72     {
 73         jobMethod.runJobNow( job );
 74         return(new ResponseEntity<Map<String, Object> > ( new HashMap<String, Object>(), HttpStatus.OK ) );
 75     }
 76 
 77 
 78     /**
 79      * 跳轉到添加定時任務的頁面
 80      * @param model
 81      *            儲存結果的實體
 82      */
 83     @RequestMapping( value = "/addJob", method = RequestMethod.GET )
 84     @Log( "初始化添加表單" )
 85     public String addForm( Model model )
 86     {
 87         model.addAttribute( "job", new ScheduleJob() );
 88         return("task/addJob");
 89     }
 90 
 91 
 92     /**
 93      * 添加定時任務記錄
 94      * @param job 任務實體
 95      */
 96     @RequestMapping( value = "/addJob", method = RequestMethod.POST )
 97     @Log( "新增操作員" )
 98     public String addUser( @ModelAttribute("job") ScheduleJob job, RedirectAttributes ra, Model model,
 99                    HttpServletRequest request )
100     {
101         SimpleDateFormat format = new SimpleDateFormat( AppConstant.DATE_FORMAT_YYYYMMDDHHMMSS );
102         job.setCreateTime( format.format( new Date() ) );
103         quartzJobService.inserJob( job );
104         ra.addFlashAttribute( "actionResult", new SuccessActionResult() );
105         return("redirect:/taskController/list.do");
106     }
107 
108 
109     /**
110      * 初始化修改表單
111      * @param jobId
112      * @return 跳轉位址
113      */
114     @RequestMapping( value = "/updateJob", method = RequestMethod.GET )
115     @Log( "初始化修改表單" )
116     public String updateForm( @RequestParam("id") Integer jobId, Model model,
117                   HttpServletRequest request )
118     {
119         ScheduleJob job = quartzJobService.getScheduleJobById( jobId );
120         model.addAttribute( "job", job );
121         return("task/updateJob");
122     }
123 
124 
125     /**
126      * 修改定時任務記錄資訊
127      * @param job 待修改的操作員實體
128      * @param model 封裝處理結果的實體
129      * @param request 請求對象
130      * @return 跳轉位址
131      */
132     @RequestMapping( value = "/updateJob", method = RequestMethod.POST )
133     @Log( "修改定時任務" )
134     public String updateJob( @ModelAttribute ScheduleJob job, RedirectAttributes ra, Model model,
135                  HttpServletRequest request )
136     {
137         SimpleDateFormat format = new SimpleDateFormat( AppConstant.DATE_FORMAT_YYYYMMDDHHMMSS );
138         job.setUpdateTime( format.format( new Date() ) );
139         quartzJobService.updateJob( job );
140         ra.addFlashAttribute( "actionResult", new SuccessActionResult() );
141         return("redirect:/taskController/list.do");
142     }
143 
144 
145     /**
146      * 删除一條定時任務記錄資訊
147      * @return
148      */
149     @RequestMapping( value = "/deleteJob" )
150     @Log( "删除任務" )
151     public String deleteJob( @RequestParam("id") int jobId, RedirectAttributes ra )
152     {
153         quartzJobService.deleteJob( jobId );
154         ra.addFlashAttribute( "actionResult", new SuccessActionResult() );
155         return("redirect:/taskController/list.do");
156     }
157 
158 
159     /**
160      * 校驗執行任務的表達式是否正确
161      * @param expression
162      * @return
163      */
164     @ResponseBody
165     @RequestMapping( value = "/checkExp", produces = "application/json;charset=utf-8" )
166     @Log( "校驗任務表達式" )
167     public ResponseEntity<Map<String, Object> > checkExpression( String expression )
168     {
169         Map<String, Object> map = new HashMap<String, Object>();
170         map.put( AppConstant.SYSTEM_JSON_CODE, AppConstant.SYSTEM_JSON_ERROR );
171         if ( jobMethod.checkCron( expression ) )
172         {
173             map.put( AppConstant.SYSTEM_JSON_CODE, AppConstant.SYSTEM_JSON_SUCCESS );
174         }
175         return(new ResponseEntity<Map<String, Object> > ( map, HttpStatus.OK ) );
176     }
177 
178 
179     /**
180      * 某個定時任務下的所有執行記錄資訊清單
181      * @param jobReq
182      * @return
183      */
184     @RequestMapping( "/itemJob" )
185     @Log( "任務執行資訊清單" )
186     public String executeJobList( @ModelAttribute("job") ScheduleJobReq jobReq, int jobId,
187                       Model model, HttpServletRequest request )
188     {
189         PaginationBean<ScheduleJobItem> pb = quartzJobService.getJobItemsByPage( jobId, jobReq );
190         try {
191             pb.setUrl( HttpUtils.getRequestInfo( request, true ) );
192         } catch ( Exception e ) {
193             log.error( "get request url error", e );
194         }
195         model.addAttribute( "pb", pb );
196         model.addAttribute( "jobId", jobId );
197         return("task/taskItemList");
198     }
199 }      

四、編寫任務運作入口,即JobMethod.java

Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)
Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)
1 package com.zealer.cps.task.manage;
  2 
  3 import java.util.List;
  4 
  5 import javax.annotation.Resource;
  6 
  7 import org.apache.commons.logging.Log;
  8 import org.apache.commons.logging.LogFactory;
  9 import org.quartz.CronScheduleBuilder;
 10 import org.quartz.CronTrigger;
 11 import org.quartz.JobBuilder;
 12 import org.quartz.JobDetail;
 13 import org.quartz.JobKey;
 14 import org.quartz.Scheduler;
 15 import org.quartz.SchedulerException;
 16 import org.quartz.TriggerBuilder;
 17 import org.quartz.TriggerKey;
 18 import org.springframework.stereotype.Component;
 19 
 20 import com.zealer.cps.task.QuartzJobFactory;
 21 import com.zealer.cps.task.service.QuartzJobService;
 22 import com.zealer.cps.task.value.ScheduleJob;
 23 
 24 
 25 /**
 26  * 提供Job任務相關的方法
 27  * @author xiaohe
 28  */
 29 @Component( "JobMethod" )
 30 public class JobMethod
 31 {
 32     @Resource( name = "schedulerFactoryBean" )
 33     private Scheduler scheduler;
 34 
 35     @Resource( name = "quartzJobService" )
 36     private QuartzJobService quartzJobService;
 37 
 38     private static Log log = LogFactory.getLog( JobMethod.class );
 39 
 40 
 41     /**
 42      * 任務架構初始化方法
 43      * @throws
 44      */
 45     public void init()
 46     {
 47         /* 從資料庫獲得所有的任務資訊記錄 */
 48         List<ScheduleJob> jobList = quartzJobService.getAllJobs();
 49 
 50         if ( jobList != null && !jobList.isEmpty() )
 51         {
 52             for ( ScheduleJob scheduleJob : jobList )
 53             {
 54                 /* 判斷任務狀态,是否為執行狀态 */
 55 
 56                 TriggerKey triggerKey = TriggerKey.triggerKey( scheduleJob
 57                                      .getJobName(), scheduleJob.getJobGroup() );
 58                 CronTrigger trigger;
 59                 try
 60                 {
 61                     trigger = (CronTrigger) scheduler.getTrigger( triggerKey );
 62                     if ( null == trigger )
 63                     {
 64                         JobDetail jobDetail = JobBuilder.newJob(
 65                             QuartzJobFactory.class ).withIdentity(
 66                             scheduleJob.getJobName(),
 67                             scheduleJob.getJobGroup() ).build();
 68 
 69                         jobDetail.getJobDataMap().put( "scheduleJob",
 70                                      scheduleJob );
 71 
 72                         CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
 73                                          .cronSchedule( scheduleJob.getCronExpression() );
 74 
 75                         trigger = TriggerBuilder.newTrigger().withIdentity(
 76                             scheduleJob.getJobName(),
 77                             scheduleJob.getJobGroup() ).withSchedule(
 78                             scheduleBuilder ).build();
 79                         scheduler.scheduleJob( jobDetail, trigger );
 80                     }else {
 81                         /* Trigger已存在,那麼更新相應的定時設定 */
 82                         CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
 83                                          .cronSchedule( scheduleJob.getCronExpression() );
 84 
 85                         /* 按新的cronExpression表達式重新建構trigger */
 86                         trigger = trigger.getTriggerBuilder().withIdentity(
 87                             triggerKey ).withSchedule( scheduleBuilder )
 88                              .build();
 89 
 90                         /* 按新的trigger重新設定job執行 */
 91                         scheduler.rescheduleJob( triggerKey, trigger );
 92                     }
 93                 }
 94                 catch ( SchedulerException e )
 95                 {
 96                     log.error( "Task init failed.", e );
 97                 }
 98             }
 99         }
100     }
101 
102 
103     /**
104      * 暫停一個job
105      *
106      * @param scheduleJob
107      * @throws SchedulerException
108      */
109     public void pauseJob( ScheduleJob scheduleJob )
110     {
111         JobKey jobKey = JobKey.jobKey( scheduleJob.getJobName(), scheduleJob.getJobGroup() );
112         try
113         {
114             scheduler.pauseJob( jobKey );
115         }
116         catch ( SchedulerException e )
117         {
118             log.error( "Task pause failed.", e );
119         }
120     }
121 
122 
123     /**
124      * 恢複一個job
125      *
126      * @param scheduleJob
127      * @throws SchedulerException
128      */
129     public void resumeJob( ScheduleJob scheduleJob )
130     {
131         JobKey jobKey = JobKey.jobKey( scheduleJob.getJobName(), scheduleJob.getJobGroup() );
132         try
133         {
134             scheduler.resumeJob( jobKey );
135         }
136         catch ( SchedulerException e )
137         {
138             log.error( "Task resume failed.", e );
139         }
140     }
141 
142 
143     /**
144      * 删除一個job
145      *
146      * @param scheduleJob
147      * @throws SchedulerException
148      */
149     public void deleteJob( ScheduleJob scheduleJob )
150     {
151         JobKey jobKey = JobKey.jobKey( scheduleJob.getJobName(), scheduleJob.getJobGroup() );
152         try
153         {
154             scheduler.deleteJob( jobKey );
155         }
156         catch ( SchedulerException e )
157         {
158             log.error( "Task delete failed.", e );
159         }
160     }
161 
162 
163     /**
164      * 立即執行job
165      *
166      * @param scheduleJob
167      * @throws SchedulerException
168      */
169     public void runJobNow( ScheduleJob scheduleJob )
170     {
171         JobKey jobKey = JobKey.jobKey( scheduleJob.getJobName(), scheduleJob.getJobGroup() );
172         try
173         {
174             scheduler.triggerJob( jobKey );
175         }
176         catch ( SchedulerException e )
177         {
178             log.error( "Task run failed.", e );
179         }
180     }
181 
182 
183     /**
184      * 更新job時間表達式
185      *
186      * @param scheduleJob
187      * @throws SchedulerException
188      */
189     public void updateJobCron( ScheduleJob scheduleJob ) throws SchedulerException
190     {
191         TriggerKey triggerKey = TriggerKey.triggerKey( scheduleJob.getJobName(),
192                              scheduleJob.getJobGroup() );
193         /* 擷取trigger,即在spring配置檔案中定義的 bean id="schedulerFactoryBean" */
194         CronTrigger trigger = (CronTrigger) scheduler.getTrigger( triggerKey );
195         /* 表達式排程建構器 */
196         CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule( scheduleJob
197                                             .getCronExpression() );
198         /*按新的cronExpression表達式重新建構trigger */
199         trigger = trigger.getTriggerBuilder().withIdentity( triggerKey )
200              .withSchedule( scheduleBuilder ).build();
201         /*按新的trigger重新設定job執行 */
202         scheduler.rescheduleJob( triggerKey, trigger );
203     }
204 
205 
206 /**
207  * 判斷表達式是否可用
208  * @param cron
209  * @return
210  * @throws
211  */
212     public boolean checkCron( String cron )
213     {
214         try
215         {
216             CronScheduleBuilder.cronSchedule( cron );
217         }
218         catch ( Exception e )
219         {
220             return(false);
221         }
222         return(true);
223     }
224 }      

 五、編寫業務層類QuartzJobService.java

Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)
Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)
1 package com.zealer.cps.task.service;
  2 
  3 import java.util.HashMap;
  4 import java.util.List;
  5 import java.util.Map;
  6 
  7 import javax.annotation.Resource;
  8 
  9 import org.springframework.stereotype.Service;
 10 import org.springframework.transaction.annotation.Propagation;
 11 import org.springframework.transaction.annotation.Transactional;
 12 
 13 import com.zealer.cps.base.dao.BaseDaoInterface;
 14 import com.zealer.cps.base.model.vo.PaginationBean;
 15 import com.zealer.cps.task.value.ScheduleJob;
 16 import com.zealer.cps.task.value.ScheduleJobItem;
 17 import com.zealer.cps.task.value.ScheduleJobReq;
 18 
 19 @Service( "quartzJobService" )
 20 public class QuartzJobService
 21 {
 22     public static final String    JOB_LIST    = "quartzJob.jobsList";
 23     public static final String    JOB_SELECT_BYID = "quartzJob.selectById";
 24     public static final String    JOB_INSERT    = "quartzJob.addJob";
 25     public static final String    JOB_UPDATE    = "quartzJob.updateJob";
 26     public static final String    JOB_DELETE    = "quartzJob.deleteJob";
 27     public static final String    JOB_LIST_PAGE    = "quartzJob.jobListPage";
 28 
 29     public static final String    JOBITEM_LIST_PAGE    = "jobItem.selectListPageByMap";
 30     public static final String    JOBITEM_INSERT        = "jobItem.insertJobItem";
 31     public static final String    JOBITEM_SELETE_BYID    = "jobItem.selectByPrimaryKey";
 32 
 33     @Resource( name = "mybatisBaseDao" )
 34     private BaseDaoInterface baseDao;
 35 
 36 
 37     /**
 38      * 擷取所有的定時任務記錄資訊
 39      * @return
 40      */
 41     public List<ScheduleJob> getAllJobs()
 42     {
 43         return(this.baseDao.queryForList( JOB_LIST, null ) );
 44     }
 45 
 46 
 47     /**
 48      * 根據id擷取任務記錄
 49      * @param id
 50      * @return
 51      */
 52     public ScheduleJob getScheduleJobById( int id )
 53     {
 54         return(this.baseDao.query( JOB_SELECT_BYID, id ) );
 55     }
 56 
 57 
 58     /**
 59      * 插入一條定時任務記錄
 60      * @param job
 61      */
 62     public void inserJob( ScheduleJob job )
 63     {
 64         this.baseDao.insertData( JOB_INSERT, job );
 65     }
 66 
 67 
 68     /**
 69      * 更新一條定時任務記錄
 70      * @param job
 71      */
 72     public void updateJob( ScheduleJob job )
 73     {
 74         this.baseDao.updateData( JOB_UPDATE, job );
 75     }
 76 
 77 
 78     /**
 79      * 删除一條定時任務記錄
 80      * @param job
 81      */
 82     public void deleteJob( int id )
 83     {
 84         this.baseDao.deleteData( JOB_DELETE, id );
 85     }
 86 
 87 
 88     /**
 89      * 分頁擷取定時任務記錄資訊
 90      * @return
 91      */
 92     public PaginationBean<ScheduleJob> getJobsByPage( ScheduleJobReq jobReq )
 93     {
 94         PaginationBean<ScheduleJob>    pb    = new PaginationBean<ScheduleJob>( jobReq.getCurrent(), 0, jobReq.getPageSize() );
 95         Map<String, Object>        map    = new HashMap<String, Object>();
 96         map.put( "page", pb );
 97         return(this.baseDao.queryForListPageByMap( JOB_LIST_PAGE, map ) );
 98     }
 99 
100 
101 /**
102  * 分頁擷取定時任務執行記錄資訊
103  * @return
104  */
105     public PaginationBean<ScheduleJobItem> getJobItemsByPage( Integer jobId, ScheduleJobReq jobReq )
106     {
107         PaginationBean<ScheduleJobItem> pb    = new PaginationBean<ScheduleJobItem>( jobReq.getCurrent(), 0, jobReq.getPageSize() );
108         Map<String, Object>        map    = new HashMap<String, Object>();
109         map.put( "jobId", jobId );
110         map.put( "page", pb );
111         return(this.baseDao.queryForListPageByMap( JOBITEM_LIST_PAGE, map ) );
112     }
113 
114 
115     /**
116      * 插入一條定時任務執行記錄資訊
117      * @param jobItem
118      */
119     @Transactional( propagation = Propagation.REQUIRED )
120     public void inserJobItem( ScheduleJobItem jobItem )
121     {
122         this.baseDao.insertData( JOBITEM_INSERT, jobItem );
123     }
124 
125 
126     /**
127      * 根據ID擷取一條定時任務執行記錄資訊
128      * @param id
129      * @return
130      */
131     public ScheduleJobItem getScheduleJobItemById( int id )
132     {
133         return(this.baseDao.query( JOBITEM_SELETE_BYID, id ) );
134     }
135 }      

六、編寫sql映射xml檔案QuartzJob.xml

Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)
Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)
1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 3 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 4 <mapper namespace="quartzJob">
 5     <resultMap id="jobsResultMap" type="com.lutongnet.cps.task.value.ScheduleJob">
 6         <result column="job_id" property="jobId" />
 7         <result column="job_name" property="jobName" />
 8         <result column="job_group" property="jobGroup" />
 9         <result column="job_status" property="jobStatus" />
10         <result column="cron_expression" property="cronExpression" />
11         <result column="bean_class" property="beanClass" />
12         <result column="execute_method" property="executeMethod" />
13         <result column="create_time" property="createTime" />
14         <result column="update_time" property="updateTime" />
15         <result column="job_desc" property="jobDesc" />
16     </resultMap>
17     <insert id="addJob" parameterType="com.lutongnet.cps.task.value.ScheduleJob">insert into task_detail (job_name, job_group, job_status, cron_expression, bean_class, execute_method, create_time, update_time, job_desc) values (#{jobName},#{jobGroup},#{jobStatus},#{cronExpression},#{beanClass},#{executeMethod},#{createTime},#{updateTime},#{jobDesc})</insert>
18     <delete id="deleteJob" parameterType="com.lutongnet.cps.task.value.ScheduleJob">delete from task_detail where job_id = #{jobId}</delete>
19     <update id="updateJob" parameterType="com.lutongnet.cps.task.value.ScheduleJob">update task_detail 
20     <set>
21         <if test="jobName != null">job_name = #{jobName},</if>
22         <if test="jobGroup != null">job_group = #{jobGroup},</if>
23         <if test="jobStatus != null">job_status = #{jobStatus},</if>
24         <if test="cronExpression != null">cron_expression = #{cronExpression},</if>
25         <if test="beanClass != null">bean_class = #{beanClass},</if>
26         <if test="executeMethod != null">execute_method = #{executeMethod},</if>
27         <if test="updateTime != null">update_time = #{updateTime},</if>
28         <if test="jobDesc != null">job_desc = #{jobDesc},</if>
29     </set>where job_id = #{jobId}</update>
30     <select id="jobListPage" resultMap="jobsResultMap" parameterType="java.util.Map">select job_name, job_group, job_status, cron_expression, bean_class, execute_method, create_time, update_time, job_desc,job_id from task_detail where 1=1 
31     <if test="createTime != null">and create_time = #{createTime}</if>
32     <if test="updateTime == null">and update_time = #{updateTime}</if>
33     <if test="beanClass != null">and bean_class = #{beanClass}</if>
34     <if test="executeMethod == null">and execute_method = #{executeMethod}</if>
35     <if test="jobStatus != null">and business_code = #{propertyGroups}</if>
36     <if test="jobName == null">and create_time = #{createTime}</if></select>
37     <select id="jobsList" resultMap="jobsResultMap" parameterType="java.util.Map">select job_name, job_group, job_status, cron_expression, bean_class, execute_method, create_time, update_time, job_desc,job_id from task_detail</select>
38 </mapper>      

七、修改和清單頁面

updateJob.jsp

Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)
Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)
1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
  2 <%@ include file="../common/common_tags.jsp" %>
  3 <!DOCTYPE html>
  4 <html lang="en">
  5 <head>
  6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  7 <title>修改定時任務</title>
  8 </head>
  9 <body>
 10 <div id="accordion" class="accordion">
 11     <div class="accordion-group">
 12         <div class="accordion-heading">
 13             <div class="title">系統管理 &gt;任務管理&gt;修改任務</div>
 14         </div>
 15         <div id="addAccordion" class="accordion-body in">
 16             <div class="accordion-inner" style="border: 0px solid red;">
 17                 <form:form action="${path}/taskController/updateJob.do" method="post" modelAttribute="job" cssClass="form-horizontal">
 18                     <form:hidden path="jobId"/>
 19                     <form:hidden path="createTime"/>
 20                     <div class="control-group">
 21                         <label class="control-label" for="jobName"><span class="help-inline input_msg_style">*</span>任務名稱</label>
 22                         <div class="controls">
 23                             <form:input path="jobName"/>
 24                             <span style="color:red" class="help-inline"></span>
 25                         </div>
 26                     </div>
 27                     
 28                     <div class="control-group">
 29                         <label class="control-label" for="jobGroup"><span class="help-inline input_msg_style">*</span>任務分組</label>
 30                         <div class="controls">
 31                             <form:input path="jobGroup"/>
 32                             <span style="color:red" class="help-inline"></span>
 33                         </div>
 34                     </div>        
 35                     <div class="control-group">
 36                         <label class="control-label"><span class="help-inline input_msg_style">*</span>任務表達式</label>
 37                         <div class="controls">
 38                             <form:input path="cronExpression"/>
 39                             <span style="color:red" class="help-inline"></span>                        
 40                         </div>
 41                     </div>
 42                     <div class="control-group">
 43                         <label class="control-label"><span class="help-inline input_msg_style">*</span>任務執行類</label>
 44                         <div class="controls">
 45                             <form:input path="beanClass"/>
 46                             <span style="color:red" class="help-inline"></span>                        
 47                         </div>
 48                     </div>
 49                     <div class="control-group">
 50                         <label class="control-label"><span class="help-inline input_msg_style">*</span>執行方法</label>
 51                         <div class="controls">
 52                             <form:input path="executeMethod"/>
 53                             <span style="color:red" class="help-inline"></span>                        
 54                         </div>
 55                     </div>
 56                     <div class="control-group">
 57                         <label class="control-label" for="jobDesc">任務描述</label>
 58                         <div class="controls">
 59                             <form:textarea path="jobDesc" rows="3" cols="20"/>
 60                             <span style="color:red" class="help-inline"></span>
 61                         </div>
 62                     </div>
 63                     <div class="form-actions">
 64                         <button class="lt_sys_commit" type="submit" 
 65                             onmouseover="this.className='lt_sys_commit2'" onmouseout="this.className='lt_sys_commit'">&nbsp;</button>
 66                         <button id="btn_back" class="lt_sys_back" type="button" 
 67                             onmouseover="this.className='lt_sys_back2'" onmouseout="this.className='lt_sys_back'">&nbsp;</button>
 68                     </div>
 69                 </form:form>
 70             </div>
 71         </div>
 72     </div>
 73 </div>
 74 <script type="text/javascript" src="<w:path/>resources/js/pc.js"></script>
 75 <script type="text/javascript">
 76     $('#job').validate({
 77         rules:{
 78             jobName:{
 79                 required:true,
 80                 maxlength:50
 81             },
 82             jobGroup:{
 83                 required:true,
 84                 maxlength:50
 85             },
 86             cronExpression: {
 87                 required:true,
 88                 maxlength:200                
 89             },
 90             beanClass: {
 91                 required:true,
 92                 maxlength:300                
 93             },
 94             executeMethod: {
 95                 required:true,
 96                 maxlength:100                
 97             },
 98             remark:{
 99                 maxlength:400,
100             }
101         },
102         messages:{
103             jobName:{
104                 required:"請輸入任務名稱",
105                 maxlength:"最長為50個字元",
106             },
107             jobGroup:{
108                 required:"請輸入任務名稱",
109                 maxlength:"最長為50個字元",
110             },
111             cronExpression:{
112                 required:"請輸入執行表達式",
113                 maxlength:'最長為200個字元',    
114             },
115             beanClass:{
116                 required:"請輸入任務執行類路徑",
117                 maxlength:'最長為300個字元',    
118             },
119             executeMethod:{
120                 required:"請輸入執行任務的方法",
121                 maxlength:'最長為100個字元',    
122             },
123             remark:{
124                 maxlength:"長度不能超過400個字元",
125             }
126         },
127         onfocusout: function(element) {
128             $(element).valid();
129         },
130         submitHandler: function(form){
131             var exp = $("#cronExpression").val();
132             $.post('${path}/taskController/checkExp.do',{'expression':exp},function(data)
133             {
134                 if(data.code==0){
135                     form.submit();
136                 }else{
137                     showSimpleMessage("輸入的表達式不正确,請重新輸入!");
138                     $("#cronExpression").focus();
139                 }
140             });
141             
142         },
143         errorElement: 'span',
144         errorPlacement: function(error, element) {
145             error.appendTo(element.next());
146         }
147     });
148 
149     $('#btn_back').click(function(){
150         window.location.href = '${path}/taskController/list.do';
151     })
152 </script>
153 </body>
154 </html>      

taskList.jsp

Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)
Spring 3整合Quartz 2實作手動設定定時任務:新增,修改,删除,暫停和恢複(附帶源碼)
1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 2 <%@ include file="../common/common_tags.jsp" %>
 3 <!DOCTYPE html>
 4 <html lang="en">
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 7 <title>任務管理&gt;任務清單</title>
 8 
 9 </head>
10 <body>
11 <div id="accordion" class="accordion">
12     <div class="accordion-group">
13         <div class="accordion-heading">
14             <div class="title">任務管理&gt;任務清單</div>
15         </div>
16         <div id="addAccordion" class="accordion-body in">
17             <div class="accordion-inner">
18                 <div style="border: 0px solid red; height: 33px;">
19                     <form:form action="${path}/taskController/list.do" method="post" modelAttribute="job" cssClass="form-inline"></form:form>
20                     <lt:img menuName="任務清單" moduleName="營運管理"></lt:img>
21                 </div>
22                 <table class="table table-hover table-condensed">
23                     <thead>
24                         <tr>
25                             <th width="4%"><input id="checkAll" name="checkAll" type="checkbox" style="margin-top: 0px;">全選</th>
26                             <th>任務名稱</th>
27                             <th>任務分組</th>
28                             <th>任務描述</th>
29                             <th>建立時間</th>
30                             <th>更新時間</th>
31                             <th>任務表達式</th>
32                             <th>執行類</th>
33                             <th>執行方法</th>
34                             <th>操作</th>
35                         </tr>
36                     </thead>
37                     <tbody>
38                         <c:forEach items="${pb.dataList}" var="job" varStatus="status">
39                             <tr>
40                                 <td><input name="checkItem" type="checkbox" value="${job.jobId}" style="margin-top: 0px;"></td>
41                                 <td>${job.jobName}</td>
42                                 <td>${job.jobGroup}</td>
43                                 <td>${job.jobDesc}</td>
44                                 <td>${job.createTime}</td>
45                                 <td>${job.updateTime}</td>
46                                 <td>${job.cronExpression}</td>
47                                 <td>${job.beanClass}</td>
48                                 <td>${job.executeMethod}</td>
49                                 <td>
50                                     <img src="${path}/resources/img/zengjian.png">
51                                     <a href="${path}/taskController/itemJob.do?jobId=${job.jobId}" >詳細</a>&nbsp;
52                                     <lt:img menuName="任務清單" moduleName="營運管理" privilegeName="執行定時任務" clickName="立即執行"
53                                         clickMethod="executeJob('${job.jobName}','${job.jobGroup}','${job.jobId}');"></lt:img>
54                                 </td>
55                             </tr>
56                         </c:forEach>
57                         <tr>
58                             <td colspan="10" form-id="job" class="paginationPanel"><ltPage:page pageBean="${pb}" /></td>
59                         </tr>
60                     </tbody>
61                 </table>
62             </div>
63         </div>
64     </div>
65 </div>
66 <script type="text/javascript">
67 
68 function executeJob(name,group,id){
69     $.ajax({
70            type: "POST",
71            url: "${path}/taskController/executeJob.do",
72            data: "jobName="+name+"&jobGroup="+group+"&jobId"+id,
73            success:function(data){
74                showSimpleMessage("定時任務已執行,執行結果請檢視詳情!");
75            }
76         });
77 }
78 
79 </script>
80 </body>
81 </html>      

 到這裡,我們的spring3 整合quartz 2的定時任務功能終于是告一段落了,對常用的一些功能進行了實作,相信可以滿足一般項目的需求了。

每一個你不滿意的當下,都有一個你不曾努力的過去