quartz与spring整合实现动态任务增删改查

来源:互联网 发布:remote desktop mac 编辑:程序博客网 时间:2024/05/16 19:21

本文最初是为了实现定时推送功能,为推送设置一个时间,到时间后推送到云巴服务器。

所以这里会用到quartz定时任务调度,而且我新增一个定时推送,同时就要新增一个定时任务。所以这里也涉及到了任务的增删改查。

以下是代码实现:

1、定时任务管理类,实现对任务的CURD

package com.qbyy.util.yunba.task;import java.util.Date;import org.quartz.JobDetail;import org.quartz.Scheduler;import org.quartz.SimpleTrigger;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.quartz.SchedulerFactoryBean;import org.springframework.stereotype.Component;/** * 定时任务管理类 *  * @author FJB * 2015年6月1日 下午3:04:10 */@SuppressWarnings("rawtypes")@Component("pushQuartzManager")public class PushQuartzManager {@Autowired<span style="white-space:pre"></span>private SchedulerFactoryBean gSchedulerFactory;      private String JOB_GROUP_NAME = "EXTJWEB_JOBGROUP_NAME";  //任务组名    private String TRIGGER_GROUP_NAME = "EXTJWEB_TRIGGERGROUP_NAME"; //触发器名        @Autowired    public void setgSchedulerFactory(SchedulerFactoryBean gSchedulerFactory) {this.gSchedulerFactory = gSchedulerFactory;}/**      * @Description: 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名      * @param jobName  任务名      * @param cls  任务     * @param time  时间设置【我这里用的是java.util.Date,这样可以直接查询出数据库的日期,并设置为定时任务的开始时间】     */  public void addJob(String jobName, Class cls, Date startTime) {          try {          System.out.println("新增定时任务"+jobName);        //Scheduler sched = schedulerFactoryBean.getScheduler();            Scheduler sched = gSchedulerFactory.getScheduler();              JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME, cls);// 任务名,任务组,任务执行类              //jobDetail.getJobDataMap().put("targetObjectId", jobName);            // 触发器              SimpleTrigger simpleTrigger =  new SimpleTrigger(jobName, TRIGGER_GROUP_NAME);            simpleTrigger.setStartTime(startTime);            simpleTrigger.setRepeatCount(0);<span style="white-space:pre"></span>//重复次数为0,不重复            sched.scheduleJob(jobDetail, simpleTrigger);            // 启动              if (!sched.isShutdown()) {                  sched.start();              }          } catch (Exception e) {              throw new RuntimeException(e);          }      }         /**     * 修改定时任务     * @param jobName 任务名     * @param time 时间     */    public void modifyJobTime(String jobName,  Date time) {          try {          //Scheduler sched = schedulerFactoryBean.getScheduler();            Scheduler sched = gSchedulerFactory.getScheduler();              SimpleTrigger trigger = (SimpleTrigger) sched.getTrigger(jobName,TRIGGER_GROUP_NAME);              if (trigger == null) {                  return;              }              Date oldTime = trigger.getStartTime();            if (!oldTime.equals(time)) {              System.out.println("时间不相等,修改时间");                JobDetail jobDetail = sched.getJobDetail(jobName,JOB_GROUP_NAME);                  Class objJobClass = jobDetail.getJobClass();                  removeJob(jobName);                  addJob(jobName, objJobClass, time);              }          } catch (Exception e) {              throw new RuntimeException(e);          }      }        /**     * 移除一个定时任务     * @param jobName     */    public void removeJob(String jobName) {          try {              Scheduler sched = gSchedulerFactory.getScheduler();              sched.pauseTrigger(jobName, TRIGGER_GROUP_NAME);// 停止触发器              sched.unscheduleJob(jobName, TRIGGER_GROUP_NAME);// 移除触发器              sched.deleteJob(jobName, JOB_GROUP_NAME);// 删除任务          } catch (Exception e) {              throw new RuntimeException(e);          }      } }


2、任务处理类,定时任务所处理的业务

package com.qbyy.util.yunba.task;import org.apache.log4j.Logger;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.quartz.SchedulerContext;import org.springframework.scheduling.quartz.QuartzJobBean;import com.wunding.service.system.PushSendServiceI;/** * 定时任务执行类 *  * @author FJB * 2015年6月1日 上午11:29:31 */public class PushQuartzJob extends QuartzJobBean  {Logger logger = Logger.getLogger(PushQuartzJob.class);//【关键】推送的业务类,不能直接通过spring注解注入,必须在xml文件中配置private PushSendServiceI pushSendService;@Overrideprotected void executeInternal(JobExecutionContext context) throws JobExecutionException {String id=""; try {                 //获取JobExecutionContext中的service对象                SchedulerContext skedCtx = context.getScheduler().getContext();                 //获取SchedulerContext中的service                //这里的service就是通过配置文件 配置的                pushSendService = (PushSendServiceI)skedCtx.get("pushSendService");                 id = context.getJobDetail().getName();pushSendService.sendPush(id);System.out.println("ID= ["+id+"] 的推送,定时发送成功");logger.info("ID= ["+id+"] 的推送,定时发送成功");} catch (Exception e) {logger.info("ID= ["+id+"] 的推送,定时发送失败");e.printStackTrace();}    }}


3、配置quartz,这个配置文件要包含到spring的总配置文件中

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"><!-- quartz的调度工厂 --><bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><property name="schedulerContextAsMap">                  <map>                      <!-- 【关键】spring 管理的service需要放到这里,才能够注入成功<span style="font-family: Arial, Helvetica, sans-serif;">PushQuartzJob 要使用到的业务类要在这里注入才能使用</span> -->                      <description>schedulerContextAsMap</description>                      <entry key="pushSendService" value-ref="pushSendServiceImpl" />                  </map>              </property>   </bean></beans>


4、业务逻辑类

@Service@Transactionalpublic class PushManageServiceImpl extends BaseService implements PushManageServiceI {@Autowiredprivate PushManageMapper pushManageMapper;@Autowiredprivate PushQuartzManager pushQuartzManager;@Overridepublic void savePush(PushManage pushManage) throws Exception {String pushId = newId();pushManage.setId(pushId);//新增定时任务,这里直接将推送消息对象的ID作为jobName,这样做的好处是,在任务执行时可以直接根据jobName到数据库中查询推送信息pushQuartzManager.addJob(pushId, PushQuartzJob.class, pushManage.getTaskpushtime());pushManageMapper.save(pushManage);}}


5、每2步中,任务执行所调用的方法所在类,任务推送类

package com.wunding.service.system.impl;import java.util.Date;import org.json.JSONException;import org.json.JSONObject;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import com.wunding.domain.system.PushManage;import com.wunding.persistence.system.PushManageMapper;import com.wunding.service.system.PushSendServiceI;import com.wunding.util.yunba.YunBaPushUtil;/** * 推送定时发送管理类 *  * @author FJB * 2015年6月2日 下午3:10:12 */@Service@Transactionalpublic class PushSendServiceImpl implements PushSendServiceI {@Autowiredprivate PushManageMapper pushManageMapper;@Autowiredprivate YunBaPushUtil yunBaPushUtil;@Overridepublic void sendPush(String id) throws Exception {PushManage pushManage = new PushManage();pushManage.setId(id);Date nowDate = new Date();pushManage.setPushtime(nowDate);pushManage.setIsavailable(1);pushManageMapper.update(pushManage);PushManage push = pushManageMapper.get(id);yunBaPublish(push);}/** * 发推送到服务器 * @param push */private void yunBaPublish(PushManage push){//调研发送推送的方法/** * ----要推送的内容---- * 1.推送内容[msg] * 2.内容id [contentId] * 3.内容类型,资讯、考试等 [contentType] * 4.推送目标人员或部门 [topic or alias] * 5.按别名或频道推送 [pushType] */try {String pushStr = "{'topic': 'topic1', 'msg': '"+push.getMessages()+"', 'qos': 1}";JSONObject json = new JSONObject(pushStr);yunBaPushUtil.getSocket().emit("publish", json);} catch (JSONException e) {e.printStackTrace();}}}


要注意的地方:第2步中注入的service类与第4步中的业务逻辑类不能是同一个类,这也是我单独提取出第5步中的类的原因,因为如果是同一个类,会存在相互注入,也就是循环注入,会报类似如下的错误:

This means that said other beans do not use the final version of the bean. This is often the 
result of S type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, 
for example.


6、特别声明:在编码过程中参考网上多个地方的代码,在这里我也提供参考的链接地址:

(1)http://blog.csdn.net/whaosy/article/details/6298686 这里参考了在Job中注入service的方法

(2)http://blog.csdn.net/pengpegv5yaya/article/details/37595889 这里参考了对定时任务的CURD

(3)http://www.ibm.com/developerworks/cn/java/j-quartz/#ibm-pcon 这里参考了SimpleTrigger


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 鱼竿最前端断了怎么办 下雨天墙壁与管道间漏水怎么办 电饭锅的电线被雨淋了怎么办 钢琴跨八度手短怎么办 弹钢琴手指不灵活怎么办呢? 理发剪不锋利了怎么办 室外宽带线断了怎么办 接宽带光纤太短怎么办 装修光纤网线太短怎么办 宽带入户线断了怎么办 电信有无线没网怎么办 墙里的网线断了怎么办 墙里网线断了怎么办 3根网线断了怎么办 剪了层次的头发怎么办 小米6充电线坏了怎么办 小米6导航信号弱怎么办 麦多多充不了电怎么办 一加数据线坏了怎么办 小米耳机泡水了怎么办 公司拖欠工资公司破产了怎么办 苹果x外壳掉漆怎么办 手机壳按键很硬怎么办 棉质白衣服染色怎么办 白棉t恤混洗染色怎么办 包包被衣服染色了怎么办 白色衣服染了菜汁怎么办 一加3t屏幕刺眼怎么办 怀孕吃了好多杏怎么办 门破了个洞怎么办 钢圈轮毂刮花了怎么办 瓷砖用刀子划了怎么办 陶瓷洗手台裂了怎么办 洗车泵水管坏了怎么办 印胶浆里面渗入了发泡浆怎么办? 管子断在水管里怎么办 衣服上的织带缩水怎么办 真丝衣服拔缝了怎么办 顾客说衣服太花怎么办 铝和碱反应变黑怎么办 40度高温多肉怎么办