Spring+Quartz 实现手动开关定时器

在之前已经讲解了如果配置静态的quartz定时器(传送门:quartz定时器 ),不知道 各位小伙伴有没有成功呢,这次分享的是动态增删停止恢复定时器; 这里通过在页面传几个参数就可以控制定时器的启用关闭,而不用修改配置文件,是不是更方便了呢。不说废话,下面开始。


需要的jar包


在上个quartz中,我们用的是quartz-all-1.6.0.jar这个包,这次我们不用这个包,用的新特新2.0之后的包,需要下载quartz-2.2.1.jar、quartz-jobs-2.2.1.jar;


applocationContext.xml中配置


在applicationContext.xml中最后面加上下面这段代码即可:


    <!-- 这句话是为了实现在job中使用注解,注入service -->
    <bean id="jobFactory" class="com.reassure.quartz.JobFactory"></bean>  
    <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
        <property name="jobFactory" ref="jobFactory"></property>  
    </bean>

创建QuartzJob继承Job


package com.reassure.quartz;

import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.reassure.sys.entity.ScheduleJob;

/**
 * 通过注解实现有状态的job
 * @author Administrator
 *
 */
@DisallowConcurrentExecution  
public class QuartzJob  implements Job{

    @Override
    public void execute(JobExecutionContext job) throws JobExecutionException {
        ScheduleJob scheduleJob = (ScheduleJob)job.getMergedJobDataMap().get("scheduleJob");  
        String name=scheduleJob.getJobName();
        System.out.println("定时器"+name+"正在运行。。。。。");
    }

}


在这里用到的jScheduleJob是自己创建的一个实体,里面存放的是一个定时任务的各个属性,原来我是准备存在数据库的,后面发现没有必要,
如果各位小伙伴有需要,就可以创建一个表,动态读取数据库。


创建ScheduleJob实体


package com.reassure.sys.entity;

public class ScheduleJob {
    
    /** 任务名称 */  
    private String jobName;  
    /** 任务分组 */  
    private String jobGroup;
    public String getJobName() {
        return jobName;
    }
    public void setJobName(String jobName) {
        this.jobName = jobName;
    }
    public String getJobGroup() {
        return jobGroup;
    }
    public void setJobGroup(String jobGroup) {
        this.jobGroup = jobGroup;
    }
    @Override
    public String toString() {
        return "ScheduleJob [jobName=" + jobName + ", jobGroup=" + jobGroup + "]";
    }  
    

}


创建controller


package com.reassure.sys.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.reassure.quartz.QuartzJob;
import com.reassure.sys.entity.ScheduleJob;


@Controller
@RequestMapping(value="quartz")
public class QuartzController {
    
    @Autowired
    private Scheduler scheduler;
    
    
    /**
     * 进入定时器管理界面
     * @param jobName
     * @param jobGroup
     * @return
     */
    @RequestMapping("/quartzPage")
    public String quartzPage(String jobName,String jobGroup){
        return "backstageViews/quartz/quartz";
    }
    
     /** 
     * 任务创建与更新(未存在的就创建,已存在的则更新) 
     * @param request 
     * @param response 
     * @param scheduleJob 
     * @param model 
     * @return 
     */  
    @RequestMapping(value="/startQuartz")  
    @ResponseBody
    public Map<String,Object> updateQuartz(HttpServletRequest request,String jobName,String jobGroup){  
        Map<String,Object> map = new HashMap<>();
        
        ScheduleJob job = new ScheduleJob();
        job.setJobGroup(jobGroup.trim());
        job.setJobName(jobName.trim());
        System.out.println(jobName+","+jobGroup);
        try {  
                //获取触发器标识  
                TriggerKey triggerKey = TriggerKey.triggerKey(jobName.trim(), jobGroup.trim());  
                //获取触发器trigger  
                CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);  
            if(null==trigger){//不存在任务  
                    //创建任务  
                    JobDetail jobDetail = JobBuilder.newJob(QuartzJob.class)  
                            .withIdentity(jobName.trim(), jobGroup.trim())  
                            .build();  
                    jobDetail.getJobDataMap().put("scheduleJob", job);  
                    //表达式调度构建器  
                    //这里的时间也可以通过页面传送过来。具体怎么写请看上一篇quartz介绍
                    CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/10 * * * * ?");  
                    //按新的cronExpression表达式构建一个新的trigger  
                    trigger = TriggerBuilder.newTrigger()  
                            .withIdentity(job.getJobName(), job.getJobGroup())  
                            .withSchedule(scheduleBuilder)  
                            .build();  
                    scheduler.scheduleJob(jobDetail, trigger);  
                }else{//存在任务  
                    // Trigger已存在,那么更新相应的定时设置  
                    //表达式调度构建器  
                
                    CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * *");  
                    //按新的cronExpression表达式重新构建trigger  
                    trigger = trigger.getTriggerBuilder()  
                            .withIdentity(triggerKey)  
                            .withSchedule(scheduleBuilder)  
                            .build();  
                    //按新的trigger重新设置job执行  
                    scheduler.rescheduleJob(triggerKey, trigger);  
                }
        } catch (SchedulerException e) {  
            e.printStackTrace();  
        }  
        map.put("msg", "success");
        map.put("code", 200);
        return map;
    }  
    
    /** 
     * 删除任务 
     * @param request 
     * @param response 
     * @param scheduleJob 
     * @param model 
     * @return 
     */  
    @RequestMapping(value="/removeQuartz")  
    public void deleteQuartz(HttpServletRequest request,String jobName,String jobGroup){  
        JobKey jobKey = JobKey.jobKey(jobName.trim(), jobGroup.trim());  
        System.out.println("删除"+jobName.trim()+"任务");
        try {  
            scheduler.deleteJob(jobKey);  
        } catch (SchedulerException e) {  
            e.printStackTrace();  
        }  
    }  
       
    /** 
     * 暂停任务 
     * @param request 
     * @param response 
     * @param job 
     * @param model 
     * @return 
     */  
    @RequestMapping(value="/pauseQuartz")  
    public void pauseQuartz(HttpServletRequest request,String jobName,String jobGroup){  
        ScheduleJob job = new ScheduleJob();
        job.setJobGroup(jobGroup);
        job.setJobName(jobName);
        System.out.println(jobName+","+jobGroup);
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);  
        try {  
            scheduler.pauseJob(jobKey);  
        } catch (SchedulerException e) {  
            e.printStackTrace();  
        }  
    }  
    
    
    /** 
     * 恢复任务 
     * @param request 
     * @param response 
     * @param scheduleJob 
     * @param model 
     * @return 
     */  
    @RequestMapping(value="/resumeQuartz")  
    public void resumeQuartz(HttpServletRequest request,String jobName,String jobGroup){  
        ScheduleJob job = new ScheduleJob();
        job.setJobGroup(jobGroup);
        job.setJobName(jobName);
        System.out.println(jobName+","+jobGroup); 
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);  
        try {  
            scheduler.resumeJob(jobKey);  
        } catch (SchedulerException e) {  
            e.printStackTrace();  
        }  
    }  

}

quartz这里是通过名字辨别每个定时器的,你开启了一个name叫aaa的定时器,那么关闭的时候,传aaa这个名字就可以关闭了。
到这里,如果你不需要在定时器里面用到spring的注入,那么就可以把applicationContext配置的文件改成:


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

然后就可以用了,当然在定时器里面用不到注入的应该很少,所以我们还得加入一段代码实现这个功能。


创建JobFactory


package com.reassure.quartz;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;

public class JobFactory extends AdaptableJobFactory {  
    
    @Autowired  
    private AutowireCapableBeanFactory capableBeanFactory;  
  
    @Override  
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {  
        //调用父类的方法  
        Object jobInstance = super.createJobInstance(bundle);  
        //进行注入  
        capableBeanFactory.autowireBean(jobInstance);  
        return jobInstance;  
    }  
      
}  

将刚才applicationContext.xml的代码改回最开始说的。然后写一个jsp页面,当然,如果闲麻烦就可以直接在浏览器地址栏上面访问,
比如我这里是:localhost:8080/[项目名]/quartz/startQuartz?jobName=aaa&jobGroup=1",
然后这个叫aaa的定时器就启动了,定时时间我已经硬编码写在了controller里面,根据需要可以修改,也可以直接在页面上面传值过来;
删除任务就是:localhost:8080/[项目名]/quartz/removeQuartz?jobName=aaa&jobGroup=1"。
到这里quartz手动开关就算是实现了,谢谢各位小伙伴们的观看~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容