Quartz与spring整合实现动态添加任务

本人小白,最近工作遇到要实现动态Job的小功能,于是自行百度学习整理了下quartz在spring中的整合,写的不对不好之处,可以直接指出。
首先准备一个普通的spring-mvc maven工程作为基础,我们在这上添加定时任务功能

开始

使用jar包
<dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>1.8.5</version>
</dependency>
配置文件中加配置

此处让job可以获取spring容器中的实例,还有bean生成方式也可以用注解,可自行选择

<bean id="jobFactory" class="cn.zzm.test.job.JobFactory"></bean>  
<bean id="schedulerFactoryBeanForStatusCheck" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
    <property name="jobFactory" ref="jobFactory"></property>  
</bean>
<bean id="quartzManagerForStatusCheck" class="cn.zzm.test.job.QuartzManagerForStatusCheck"></bean>
相关class
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;  
    }
}

下面是主要代码

public class QuartzManagerForStatusCheck
{
    @Autowired
    @Qualifier("schedulerFactoryBeanForStatusCheck")
    private SchedulerFactoryBean schedulerFactoryBean; 

    private String JOB_GROUP_NAME = "STATUS_CHECK";

    private String TRIGGER_GROUP_NAME = "STATUS_CHECK_Trigger";

    /**
     * @Description: 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
     * 
     * @param jobName 任务名
     * @param cls 任务
     * @param time 时间设置,参考quartz说明文档
     * 
     */
    public void addJob(String jobName, Class<?> cls, String time)
    {
        System.setProperty("org.terracotta.quartz.skipUpdateCheck","true");
        try
        {
            Scheduler sched = schedulerFactoryBean.getScheduler();
            JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME, cls);// 任务名,任务组,任务执行类(见下面类)
            // 触发器
            CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组
            trigger.setCronExpression(time);// 触发器时间设定

            // 5分钟后重新启动
            //trigger.setStartTime(new Date(new Date().getTime() + 5000 * 60));
            sched.scheduleJob(jobDetail, trigger);
            // 启动
            if (!sched.isShutdown())
            {
                sched.start();
            }
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: 添加一个定时任务
     * 
     * @param jobName 任务名
     * @param jobGroupName 任务组名
     * @param triggerName 触发器名
     * @param triggerGroupName 触发器组名
     * @param jobClass 任务
     * @param time 时间设置,参考quartz说明文档
     * 
     */
    public void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName,
        Class<?> jobClass, String time)
    {
        try
        {
            Scheduler sched = schedulerFactoryBean.getScheduler();
            JobDetail jobDetail = new JobDetail(jobName, jobGroupName, jobClass);// 任务名,任务组,任务执行类
            // 触发器
            CronTrigger trigger = new CronTrigger(triggerName, triggerGroupName);// 触发器名,触发器组
            trigger.setCronExpression(time);// 触发器时间设定
            sched.scheduleJob(jobDetail, trigger);
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名)
     * 
     * @param jobName
     * @param time
     * 
     */
    public void modifyJobTime(String jobName, String time)
    {
        try
        {
            Scheduler sched = schedulerFactoryBean.getScheduler();
            CronTrigger trigger = (CronTrigger)sched.getTrigger(jobName, TRIGGER_GROUP_NAME);
            if (trigger == null)
            {
                return;
            }
            String oldTime = trigger.getCronExpression();
            if (!oldTime.equalsIgnoreCase(time))
            {
                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);
        }
    }

    /**
     * @Description: 修改一个任务的触发时间
     * 
     * @param triggerName
     * @param triggerGroupName
     * @param time
     * 
     * 
     */
    public void modifyJobTime(String triggerName, String triggerGroupName, String time)
    {
        try
        {
            Scheduler sched = schedulerFactoryBean.getScheduler();
            CronTrigger trigger = (CronTrigger)sched.getTrigger(triggerName, triggerGroupName);
            if (trigger == null)
            {
                return;
            }
            String oldTime = trigger.getCronExpression();
            if (!oldTime.equalsIgnoreCase(time))
            {
                CronTrigger ct = (CronTrigger)trigger;
                // 修改时间
                ct.setCronExpression(time);
                // 重启触发器
                sched.resumeTrigger(triggerName, triggerGroupName);
            }
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: 移除一个任务(使用默认的任务组名,触发器名,触发器组名)
     * 
     * @param jobName
     * 
     * 
     */
    public void removeJob(String jobName)
    {
        try
        {
            Scheduler sched = schedulerFactoryBean.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);
        }
    }

  /**
     * @Description:启动所有定时任务
     * 
     * 
     * 
     */
    public void startJobs()
    {
        try
        {
            Scheduler sched = schedulerFactoryBean.getScheduler();
            sched.start();
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description:关闭所有定时任务
     * 
     * 
     * 
     */
    public void shutdownJobs()
    {
        try
        {
            Scheduler sched = schedulerFactoryBean.getScheduler();
            if (!sched.isShutdown())
            {
                sched.shutdown();
            }
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    public List<Map<String,Object>> queryAllJobs(){
        List<Map<String,Object>> jobs = new ArrayList<Map<String,Object>>();
        try{
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            for (String groupName : scheduler.getJobGroupNames()) {
                for (String jobName : scheduler.getJobNames(groupName)) {
                    Map<String,Object> job = new HashMap<String,Object>();
                    Trigger[] triggers = scheduler.getTriggersOfJob(jobName,groupName);
                    Date nextFireTime = triggers[0].getNextFireTime();
                    System.out.println("[jobName] : " + jobName + " [groupName] : "
                    + groupName + " - " + nextFireTime);
                    job.put("jobName", jobName);
                    job.put("groupName", groupName);
                    job.put("nextFireTime", nextFireTime);
                    jobs.add(job);
                }
            }
            return jobs;
        }catch(Exception e){
             throw new RuntimeException(e);
        }
    }

}

自己写个类实现Job接口就可以作为定时任务传入上面类的add方法就可以执行。
如下Job可以注入spring bean (该Job是远程执行linux命名查看对应机器程序是否正常,不正常的发邮件,整合远程执行命令和发邮件,稍后再写。。。)

public class StatusCheckJob implements Job{

    Logger logger = LoggerFactory.getLogger(StatusCheckJob.class);

    @Autowired
    private StatusCheckService statusCheckService;

    @Autowired
    private MailForStatusCheck mailForStatusCheck;

    @Override
    public void execute(JobExecutionContext context)
            throws JobExecutionException {
        logger.info("开始运行服务状态检查Job。。。");
        List<ShipIp> ships = statusCheckService.queryAllShipIp();
        logger.debug("查询船只ip",ships);
        List<String> all = new ArrayList<String>();
        for(ShipIp ship : ships){
            try{
                List<String> r = statusCheckService.checkStatus(ship);
                all.addAll(r);
            }catch(Exception e){
                logger.error("",e);
            }

        }
        if(all.size()>0){//有异常
            logger.info("存在异常开始发送邮件。。。。。。。。。。。。。。。。。。。。");
            List<String> receivers= statusCheckService.queryAllReceiver();
            mailForStatusCheck.sendMail(all.toString(),"船端进程异常邮件",receivers);
            logger.info("邮件发送完毕。。。。。。。。。。。。。。。。。。。。。。。。。");
        }
        logger.info("服务状态检查Job结束。。。");
    }

}

自己写个接口,测试下

@ResponseBody
@RequestMapping("addJobs")
public String addJobs(String jobName,String time){
    try{
        String[] t = time.split(":");
        //String jobTime = "0 "+t[1]+" "+t[0]+" * * ?";
        quartzManagerForStatusCheck.addJob(jobName, StatusCheckJob.class, "0 0/3 * * * ?");//从0分0秒 3分钟执行一次 这边直接注入工具类了
    }catch(Exception e){
        logger.error("job:"+jobName+"添加失败",e);
        return "-1";
    }
    return "1";
}

搞定,本人撸代码没多久,写的很丑,记下学到的东西,相互学习。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值