动态创建quartz作业

动态创建quartz作业

最近在公司的业务中遇到了需要动态创建quartz作业的需求(在定时推送任务创建后,还可以更改任务的执行方法、时间、参数等),这对于之前没用过quartz的我来说十分蛋疼。但在捣鼓了两三天后,还是做了出来,回过头再看也不是很难,这里记录一下大致的使用方法。

  • spring版本4.1.6
  • quartz版本2.2.1

1.首先新增一个JobDetail类,需要继承org.springframework.scheduling.quartz.QuartzJobBean类。如下:

此处命名为MyJobDetail

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.lang.reflect.Method;

/**
 * 带参的JobClass
 * Created by xiaoming on 2017/5/4.
 */
public class MyJobClass extends QuartzJobBean {
    private Log logger = LogFactory.getLog(JobDetailWithParamBean.class);
    private String targetObject;   //执行job的对象
    private String targetMethod;   //执行job的方法
    private Object arguments;      //执行job的方法参数(如果方法不带参可以删除此参数)
    private ApplicationContext ctx;//ApplicationContext

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {

        try {
            //从ApplicationContext中获取job对象
            Object bean = ctx.getBean(targetObject);
            //通过反射获取job方法
            Method m = bean.getClass().getMethod(targetMethod,String.class);
            //执行方法(带参)
            m.invoke(bean, arguments);
            //执行方法(不带参)
            //m.invoke(bean, null);
        } catch (Exception e) {
            logger.error(e);
        }
    }
    //以下是注入方法
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.ctx = applicationContext;
    }

    public void setTargetObject(String targetObject) {
        this.targetObject = targetObject;
    }

    public void setTargetMethod(String targetMethod) {
        this.targetMethod = targetMethod;
    }

    public void setArguments(Object arguments) {
        this.arguments = arguments;
    }
}

2.创建一个作业对象。如下:

此处命名为MyJob

public class MyJob {
   public myMethod(String arguments){
      /*
         业务逻辑
      */
      Date currentTime = new Date();
      System.out.println(currentTime + "执行了作业方法,参数为:"+arguments);
   } 
}

在spring-application-task.xml中注册MyJob
quartz的配置就不贴了

<bean id="MyJob" class="com.xxx.MyJob"/>

3.创建一个作业对象的管理类。如下:

此处命名为JobManager

import com.mrwind.common.framework.spring.SpringContextHolder;
import com.mrwind.common.timeJob.MyJobDetail;
import org.quartz.*;
import org.quartz.utils.Key;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.stereotype.Service;

/**
 * Created by xiaoming on 2017/5/10.
 * 动态管理trigger类
 */
@Service
public class JobManager {

    //公用scheduler
    private static Scheduler scheduler = (Scheduler)SpringContextHolder.getApplicationContext().getBean("schedulerFactory");

    /**
     * 清空定时作业
     * 由于更新可能影响到执行的方法、时间等,并不能简单的只更改cron表达式,因此需要先删除相关作业再重新创建
     * 仅更改时间可通过更改cron表达式来更新trigger的方法,不需要删除,这里不做赘述。
     * 
     * @Param : scheduler       公用scheduler
     * @Param : keyStringList   triggerKey字符串集合
     */

    private void clearScheduler(Scheduler scheduler,List<String> keyStringList)throws Exception{
          for(String keyString : keyStringList){
            //根据keyString和group获取TriggerKey(本例中为默认group)
            TriggerKey triggerKey = TriggerKey.triggerKey(keyString, Key.DEFAULT_GROUP);
            //根据TriggerKey获取trigger
            CronTrigger trigger = (CronTrigger)scheduler.getTrigger(triggerKey);

            if(trigger != null){
                scheduler.pauseTrigger(triggerKey);      // 停止触发器
                scheduler.unscheduleJob(triggerKey);     // 移除触发器
                scheduler.deleteJob(trigger.getJobKey());// 删除任务
            }
        }
    }


    /**
     * 创建一个定时任务
     * @return triggerKey
     * @Param scheduler    公用scheduler
     * @Param targetTime   目标执行时间
     * @Param objectName   作业对象名
     * @Param method       作业方法
     * @Param arguments    作业参数
     */
    private void createSheduler(Scheduler scheduler, 
                                  Date targetTime,
                                  String objectName,
                                  String method,
                                  Object arguments
                                  )throws Exception{
        //判断是否过期
        if(targetTime.after(Calendar.getInstance().getTime())){
            String jobName,keyString;

            /*
               业务逻辑定义jobName、keyString
            */

            // 新建一个基于Spring的管理Job类
            JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();

            Map<String,String> jobDataAsMap = new HashMap<>();
            jobDataAsMap.put("targetObject",objectName);             //作业对象
            jobDataAsMap.put("targetMethod",method);                 //作业方法
            jobDataAsMap.put("arguments",arguments);                 //作业方法的参数
            jobDetailFactoryBean.setName(jobName);                   //job类命名
            jobDetailFactoryBean.setJobDataAsMap(jobDataAsMap);     
            jobDetailFactoryBean.setJobClass(MyJobClass.class);      //JobClass,就是在1中定义的类
            jobDetailFactoryBean.afterPropertiesSet();

            JobDetail jobDetail = jobDetailFactoryBean.getObject();  //获取JobDetail对象
            String cronExpression = createCronExpression(targetTime);//创建cron表达式
            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
            // 根据cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(keyString,Key.DEFAULT_GROUP)
                    .withSchedule(scheduleBuilder).build();
            // 注入到管理类
            scheduler.scheduleJob(jobDetail, trigger);
        }
    }


    /**
     * 创建cron表达式(此处为创建指定的时间点)
     * @param targetTime
     * @return
     */
    private String createCronExpression(Date targetTime){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(remindTime);
        int min = calendar.get(Calendar.MINUTE);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int day = calendar.get(Calendar.DATE);
        int mon = calendar.get(Calendar.MONTH) + 1;
        int year = calendar.get(Calendar.YEAR);

        String cronExpression = "0 "+min+" "+hour+" "+day+" "+mon+" ? "+year;
        return cronExpression;
    }
}

Note:第一篇csdn博客结束。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值