一、ScheduleJob实体类介绍

  

public class ScheduleJob implements Serializable
{
  public static String STATUS_RUNNING = "1";
  public static final String STATUS_NOT_RUNNING = "0";
  public static final String CONCURRENT_IS = "1";
  public static final String CONCURRENT_NOT = "0";

  /**
  * 自己定义的组名与类名
  */
  public static final String EXAM_NAME = "EXAM_NAME";
  public static final String EXAM_GROUP = "EXAM_GROUP";

  private Long jobId;
  private Date createTime;
  private Date endTime;
  private Date updateTime;
  /**
  * 任务名称 必须
  */
  private String jobName;
  /**
  * 任务分组 必须
  */
  private String jobGroup;
  /**
  * 任务状态 是否启动任务
  */
  private String jobStatus;
  /**
  * cron表达式 必须
  */
  private String cronExpression;
  /**
  * 描述
  */
  private String description;
  /**
  * 任务执行时调用哪个类的方法 包名+类名
  */
  private String beanClass;
  /**
  * 任务是否有状态
  */
  private String isConcurrent;
  /**
  * spring bean 指定springId方式可不指定beanClass
  */
  private String springId;
  /**
  * 任务调用的方法名 
  */
  private String methodName;

}

二、简单的demo

  //在线考试动态任务实例
  ScheduleJob scheduleJob = new ScheduleJob();
  scheduleJob.setJobId(1L);
  scheduleJob.setJobName(QuartzManager.getExamName());
  scheduleJob.setJobGroup(QuartzManager.getExamGroup());
  scheduleJob.setJobStatus(ScheduleJob.STATUS_RUNNING);

  //设定定时器调用的方法路径,一般调用Service中的方法 此实例调用answerResultService中的updateTimer方法
  scheduleJob.setSpringId("answerResultService");
  scheduleJob.setMethodName("updateTimer");
  scheduleJob.setIsConcurrent(ScheduleJob.CONCURRENT_IS);
  scheduleJob.setCreateTime(new Date());
  int limittime = examina.getLimittime();
  Date endTime = DateUtils.getAboutSecond(scheduleJob.getCreateTime(),limittime);
  scheduleJob.setEndTime(endTime);
  /**
  * 参数设置非必须,视定时器调用的函数是否需要传参而定,Object数组传参适用于各种类型的参数
  */

  HashMap map = new HashMap();
  Class[] cArg = new Class[]{String.class}; 
  Object[] objects = new Object[]{answerResult.getId()};
  map.put("clazz", cArg);
  map.put("values", objects);

  quartzManager.addTriggerJob(scheduleJob,map);

三、动态管理定时器

  /**
  * 添加一个定时器
  * @param job
  * @param map
  * @throws SchedulerException
  */

  public void addTriggerJob(ScheduleJob job,Map map) throws SchedulerException
  {
    if (job == null || !ScheduleJob.STATUS_RUNNING.equals(job.getJobStatus()))
    {
      return;
    }
    Scheduler scheduler = SpringUtils.getBean(SchedulerFactoryBean.class).getScheduler();
    TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(),job.getJobGroup());
    //此定时器于创建日期立即执行,在规定时间结束,期间1s执行一次
    SimpleTrigger simpleTrigger =

      (SimpleTrigger) TriggerBuilder.newTrigger().

      withIdentity(job.getJobName(),job.getJobGroup()).

      startAt(job.getCreateTime()).endAt(job.getEndTime()).

      withSchedule(SimpleScheduleBuilder.simpleSchedule().

      withIntervalInSeconds(1).repeatForever()).build();

    //此定时器在规定时间执行,切执行一次

    //SimpleTrigger simpleTrigger =

      (SimpleTrigger) TriggerBuilder.newTrigger().

      withIdentity(job.getJobName(), job.getJobGroup()).

      startAt(startTime).build();

    //此定时器在规定时间执行,期间以规定的时间间隔执行一次或数次,无结束日期,在定时任务删除时结束

    //SimpleTrigger simpleTrigger =

      (SimpleTrigger)TriggerBuilder.newTrigger().

      withIdentity(job.getJobName(),job.getJobGroup()).

      startAt(startTime).

      withSchedule(SimpleScheduleBuilder.simpleSchedule() .

      withIntervalInHours(space).repeatForever()).build();

 

    Class clazz = ScheduleJob.CONCURRENT_IS.equals(job.getIsConcurrent())

    ? QuartzJobFactory.class: QuartzJobFactoryDisallowConcurrentExecution.class;
    JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(job.getJobName(),

    job.getJobGroup()).build();

    jobDetail.getJobDataMap().put("scheduleJob", job);
    jobDetail.getJobDataMap().put("map", map);
    Date date = scheduler.scheduleJob(jobDetail,simpleTrigger );
    System.out.println(jobDetail.getKey() + " will run at: " + date + " and repeat: "+ simpleTrigger.getRepeatCount()

    + " times, every " + simpleTrigger.getRepeatInterval() / 1000L + " seconds");
  }

  /**
  * 获取所有计划中的任务列表
  * 
  * @return
  * @throws SchedulerException
  */
  public List<ScheduleJob> getAllJob() throws SchedulerException
  {
    Scheduler scheduler = SpringUtils.getBean(SchedulerFactoryBean.class).getScheduler();
    GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
    Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
    List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
    for (JobKey jobKey : jobKeys)
    {
      List<? extends Trigger> triggers = scheduler
      .getTriggersOfJob(jobKey);
      for (Trigger trigger : triggers)
      {
        ScheduleJob job = new ScheduleJob();
        job.setJobName(jobKey.getName());
        job.setJobGroup(jobKey.getGroup());
        job.setDescription("触发器:" + trigger.getKey());
        Trigger.TriggerState triggerState = scheduler
        .getTriggerState(trigger.getKey());
        job.setJobStatus(triggerState.name());
        if (trigger instanceof CronTrigger)
        {
          CronTrigger cronTrigger = (CronTrigger) trigger;
          String cronExpression = cronTrigger.getCronExpression();
          job.setCronExpression(cronExpression);
        }
        jobList.add(job);
      }
    }
    return jobList;
  } 

  /**
  * 所有正在运行的job
  * 
  * @return
  * @throws SchedulerException
  */
  public List<ScheduleJob> getRunningJob() throws SchedulerException
  {
    Scheduler scheduler = SpringUtils.getBean(SchedulerFactoryBean.class).getScheduler();
    List<JobExecutionContext> executingJobs = scheduler
    .getCurrentlyExecutingJobs();
    List<ScheduleJob> jobList = new ArrayList<ScheduleJob>(
    executingJobs.size());
    for (JobExecutionContext executingJob : executingJobs)
    {
      ScheduleJob job = new ScheduleJob();
      JobDetail jobDetail = executingJob.getJobDetail();
      JobKey jobKey = jobDetail.getKey();
      Trigger trigger = executingJob.getTrigger();
      job.setJobName(jobKey.getName());
      job.setJobGroup(jobKey.getGroup());
      job.setDescription("触发器:" + trigger.getKey());
      Trigger.TriggerState triggerState = scheduler
      .getTriggerState(trigger.getKey());
      job.setJobStatus(triggerState.name());
      if (trigger instanceof CronTrigger)
      {
        CronTrigger cronTrigger = (CronTrigger) trigger;
        String cronExpression = cronTrigger.getCronExpression();
        job.setCronExpression(cronExpression);
      }
      jobList.add(job);
    }
    return jobList;
  }

  /**
  * 暂停一个job
  * 
  * @param scheduleJob
  * @throws SchedulerException
  */
  public void pauseJob(ScheduleJob scheduleJob) throws SchedulerException
  {
    Scheduler scheduler = SpringUtils.getBean(SchedulerFactoryBean.class).getScheduler();
    JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(),scheduleJob.getJobGroup());
    scheduler.pauseJob(jobKey);
  }

  /**
  * 恢复一个job
  * 
  * @param scheduleJob
  * @throws SchedulerException
  */
  public void resumeJob(ScheduleJob scheduleJob) throws SchedulerException
  {
    Scheduler scheduler = SpringUtils.getBean(SchedulerFactoryBean.class).getScheduler();
    JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(),scheduleJob.getJobGroup());
    scheduler.resumeJob(jobKey);
  }

  /**
  * 删除一个job
  * 
  * @param scheduleJob
  * @throws SchedulerException
  */
  public void deleteJob(String jobName, String jobGroup) throws SchedulerException
  {
    Scheduler scheduler = SpringUtils.getBean(SchedulerFactoryBean.class).getScheduler();
    JobKey jobKey = JobKey.jobKey(jobName,
    jobGroup);
    scheduler.deleteJob(jobKey);
  }

  /**
  * 立即执行job
  * 
  * @param scheduleJob
  * @throws SchedulerException
  */
  public void runAJobNow(ScheduleJob scheduleJob) throws SchedulerException
  {
    Scheduler scheduler = SpringUtils.getBean(SchedulerFactoryBean.class).getScheduler();
    JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(),
    scheduleJob.getJobGroup());
    scheduler.triggerJob(jobKey);
  }

四、定时器执行流程

  

  /**
  * 计划任务执行处 无状态 并发执行
  * @author zdw
  * 有状态,添加@DisallowConcurrentExecution注解进行取消并发
  */
  public class QuartzJobFactory implements Job
  {

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException
    {
      ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
      TaskUtils.invokMethod(scheduleJob,context); 
    }
  }

  /** 
  * 通过反射调用scheduleJob中定义的方法 
  * 
  * @param scheduleJob 
  */ 

  public static void invokMethod(ScheduleJob scheduleJob,JobExecutionContext context) { 
    Object object = null; 
    Class clazz = null; 
    //springId不为空先按springId查找bean
    if (StringUtils.isNotEmpty(scheduleJob.getSpringId())) { 
      object = SpringUtils.getBean(scheduleJob.getSpringId());
    } else if (StringUtils.isNotEmpty(scheduleJob.getBeanClass())) { 
      try { 
        clazz = Class.forName(scheduleJob.getBeanClass()); 
        object = clazz.newInstance(); 
      } catch (Exception e) { 
        e.printStackTrace(); 
      } 

    } 
    if (object == null) {
      log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,请检查是否配置正确!!!"); 
      return; 
    } 
    clazz = object.getClass(); 
    Method method = null; 
    JobDataMap jdm = context.getMergedJobDataMap();
    HashMap map = (HashMap) jdm.get("map");
    if(map != null || map.size() != 0){
    Class[] cArg = (Class[]) map.get("clazz");
    Object[] values = (Object[]) map.get("values");
    try {
      method = clazz.getDeclaredMethod(scheduleJob.getMethodName(),cArg); 
    } catch (NoSuchMethodException e) { 
      log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,方法名设置错误!!!"); 
    } catch (SecurityException e) { 
      e.printStackTrace(); 
    } 
    if (method != null) { 
      try { 
        method.invoke(object,values); 
      } catch (IllegalAccessException e) { 
        e.printStackTrace(); 
      } catch (IllegalArgumentException e) { 
        e.printStackTrace(); 
      } catch (InvocationTargetException e) { 
        e.printStackTrace(); 
      } 
    }
  } else{
    try {
      method = clazz.getDeclaredMethod(scheduleJob.getMethodName()); 
    } catch (NoSuchMethodException e) { 
      log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,方法名设置错误!!!"); 
    } catch (SecurityException e) { 
      e.printStackTrace(); 
    } 
    if (method != null) { 
      try { 
        method.invoke(object); 
      } catch (IllegalAccessException e) { 
        e.printStackTrace(); 
      } catch (IllegalArgumentException e) { 
        e.printStackTrace(); 
      } catch (InvocationTargetException e) { 
        e.printStackTrace(); 
        } 
      }
    }
  }

五、配置相关

pom.xml

<!-- quartz -->
  <dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.2</version>
  </dependency>
  <dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz-jobs</artifactId>
    <version>2.2.2</version>
  </dependency>

applicationContext-quartz-cron-local.xml

   <description>Quartz的本地Cron式执行任务配置</description>
    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
   <!-- Job接受applicationContext的成员变量名 -->
    <property name="applicationContextSchedulerContextKey" value="applicationContext" />
    </bean>

applicationContext-quartz-timer-cluster.xml

  <description>Quartz的定时集群任务配置</description>

  <!-- Quartz集群Schduler -->
    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
  <!-- Triggers集成 -->
    <property name="triggers">
  <list>
  </list>
  </property>
  <!-- quartz配置文件路径, 指向cluster配置 -->
    <property name="configLocation" value="classpath:schedule/quartz-cluster.properties" />
  <!-- 启动时延期2秒开始任务 -->
    <property name="startupDelay" value="30" />
  <!-- 保存Job数据到数据库所需的数据源 -->
    <property name="dataSource" ref="quartzDataSource" /> 
  <!-- Job接受applicationContext的成员变量名 -->
    <property name="applicationContextSchedulerContextKey" value="applicationContext" />
  </bean>
  <!-- Job的可配置属性,在job中通过applicationContext动态获取 -->
  <util:map id="timerJobConfig">
    <entry key="nodeName" value="${server.node_name}" />
  </util:map>

更多推荐

JAVA动态任务SCHEDULEJOB