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中最后面加上下面这段代码即可:


    
      
      
          
    

创建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 updateQuartz(HttpServletRequest request,String jobName,String jobGroup){  
        Map 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配置的文件改成:




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


创建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手动开关就算是实现了,谢谢各位小伙伴们的观看~

你可能感兴趣的:(Spring+Quartz 实现手动开关定时器)