Quartz定时任务的组件API[通俗易懂]

title:Quartz技术(二)-Quartz组件APIcategories:后端tags:定时任务本讲主要说明Quartz中重要的几个组件的API。Scheduler(调度器)Scheduler的生命期,从SchedulerFactory创建它时开始,到Scheduler调用shutdown()方法时结束;Scheduler被创建后,可以增加、删除和列举Job和Tri…

大家好,又见面了,我是你们的朋友全栈君。

个人博客:https://domyselfzy.coding.me/

本讲主要说明Quartz中重要的几个组件的API。

Scheduler(调度器)

Scheduler的生命期,从SchedulerFactory创建它时开始,到Scheduler调用shutdown()方法时结束;Scheduler被创建后,可以增加、删除和列举Job和Trigger,以及执行其它与调度相关的操作(如暂停Trigger)。但是,Scheduler只有在调用start()方法后,才会真正地触发trigger(即执行job)。

上面说了,Scheduler是由Factory创建的,有两种方式来创建一个Scheduler。

  1. 直接获取
// 1. 创建 SchedulerFactory
SchedulerFactory factory = new StdSchedulerFactory();
// 2. 从工厂中获取调度器实例
Scheduler scheduler = factory.getScheduler();
  1. 自己配置FactoryBean
/** * <p>初始化一个构建Scheduler的工厂</p> */
@Bean
public SchedulerFactoryBean schedulerFactoryBean() throws Exception { 
   
    SchedulerFactoryBean factory = new SchedulerFactoryBean();
    factory.setQuartzProperties(quartzProperties());
    factory.setOverwriteExistingJobs(true);
    factory.afterPropertiesSet();
    return factory;
}

/** * 通过SchedulerFactoryBean获取Scheduler的实例 */
@Bean
public Scheduler scheduler() throws Exception { 
   
    Scheduler scheduler = schedulerFactoryBean().getScheduler();
    if (scheduler.isStarted()) { 
   
        scheduler.shutdown();
    }

		scheduler.start();
    return scheduler;
}

第二种方式,有一个好处,可以初始化指定的配置文件,也不一定必须放在ClassPath的指定位置。

Job

一个job就是一个实现了Job接口的类,该接口只有一个方法:

public interface Job { 
   

public void execute(JobExecutionContext context)
  throws JobExecutionException;
}

简单来说,Job的使命就是你将需要执行的任务逻辑,写在execute()方法中。
当一个定时任务被执行时,execute()方法由调度程序的一个线程调用。
我们可以在Job中定义自己当前作业需要执行的逻辑,如:

@Override
@SuppressWarnings("unchecked")
@Transactional(rollbackFor = Exception.class)
public void execute(JobExecutionContext jobExecutionContext) { 
   
    JobDetail jobDetail = jobExecutionContext.getJobDetail();
    JobDataMap jobDataMap = jobDetail.getJobDataMap();
   
    messageTemplate = (RedisTemplate<String, String>) jobDataMap.get("messageTemplate");
    scheduler = (Scheduler) jobDataMap.get("scheduler");

    //处理分布式的锁问题
    String lockName = QuartzConstants.LOCK_KEY + QuartzConstants.JMS_JOIN_SIGN + task.getId();
    Boolean absent = messageTemplate.opsForValue().setIfAbsent(lockName, "task-job-lock");
    try { 
   
        if (BooleanUtils.isNotTrue(absent)) { 
   
            logger.info("Get lock fail, current job is executing , please wait next invoke , task {}"
                    , task.toString());
            return;
        }

        //避免程序服务挂掉,导致锁无法释放,设定20s,避免定时任务相距时间太短,如果有问题,再调整
        messageTemplate.expire(lockName, 20, TimeUnit.SECONDS);
    } catch (Exception e) { 
   
        e.printStackTrace();
        logger.error("send message error, task: {}", task.toString());
    } finally { 
   
        if (BooleanUtils.isTrue(absent)) { 
   
            logger.info("Free lock");
            messageTemplate.delete(lockName);
        }
    }
}

上面代码,就定义了一个我自己的逻辑,处理多机集群时,同步触发的任务锁。

JobExecutionContext

这个对象实例,将包含作业执行过程的上下文信息,可以在执行当前任务过程中获取相应信息。同时,你也可以在创建一个定时任务时将自己需要的信息放入到该上下文中。
**注意:**JobExecutionContext对象中保存着该job运行时的一些信息 ,执行job的scheduler的引用,触发job的trigger的引用,JobDetail对象引用,以及一些其它信息。

JobDetail(实例化作业)

上面说的Job,其实并不是真正可以执行的作业任务,它只是定义了一个作业能做什么,需要做什么事。真正需要被任务调度的其实的一个实例化Job的JobDetail。你可以有两种理解方式,一种是Job是一个父类,JobDetail是它的实现类(当然实际并不是,这里只是方便理解),二是,JobDetail类似Java中Number这样的包装类,将Job包装了一次,并且封装了更多的信息。

如何实例化一个JobDetail呢?

// define the job and tie it to our HelloJob class
JobDetail job = newJob(HelloJob.class)
  .withIdentity("myJob", "group1") // name "myJob", group "group1"
  .build();

很简单,只需要将你需要执行的一个Job,直接丢给JobDetail就可以了。
但是要特别注意就是,你传入个Map中的对象序列号的问题,建议采用Java标准序列化。
除此之外,上文也说了,JobExecutionContext不是还可以包含一些自定义信息吗?,在这里就可以定义了。

JobDataMap

在JobDetail中,可以使用JobDataMap来设置更多你需要带入到Job中的信息。
构建JobDetail时,可以将数据放入Map中

// define the job and tie it to our DumbJob class
JobDetail job = newJob(DumbJob.class)
  .withIdentity("myJob", "group1") // name "myJob", group "group1"
  .usingJobData("jobSays", "Hello World!")
  .usingJobData("myFloatValue", 3.141f)
  .build();

在Job执行过程中,可以从中取出来相应数据。

public class DumbJob implements Job { 
   

    public DumbJob() { 
   
    }

    public void execute(JobExecutionContext context)
      throws JobExecutionException
    { 
   
      JobKey key = context.getJobDetail().getKey();

      JobDataMap dataMap = context.getJobDetail().getJobDataMap();

      String jobSays = dataMap.getString("jobSays");
      float myFloatValue = dataMap.getFloat("myFloatValue");

      System.err.println("Instance " + key + " of DumbJob says: " + jobSays + ", and val is: " + myFloatValue);
    }
  }

好了,看到这里,不知道大家有没有疑惑?为啥好多地方都定义了withIdentity这个语句?

这里说明一下Quartz中Key的作用

Key(Job或者Trigger的唯一表示)

简答来说,不管是Job还是Trigger都要有个名字,Quartz还可以对其进行分组,这两样加起来正好作为了它的唯一标识。

将Job和Trigger注册到Scheduler时,可以为它们设置key,配置其身份属性。Job和Trigger的key(JobKey和TriggerKey)可以用于将Job和Trigger放到不同的分组(group)里,然后基于分组进行操作。同一个分组下的Job或Trigger的名称必须唯一,即一个Job或Trigger的key由名称(name)和分组(group)组成。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/127455.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • MongoDB 基础

    MongoDB 基础

  • Android代码混淆

    Android代码混淆

    2021年11月29日
  • 一个二线城市程序员-周末一天的生活

    做一个积极的人编码、改bug、提升自己我有一个乐园,面向编程,春暖花开本文是记录我自己周末一天简单平凡的生活!我是一个在二线城市工作和生活的程序员,在忙碌的了一周结束后,有短暂的周末得以休息和调整,做一些自己想做的事情,看一本书籍,听听音乐,抑或是刷一刷娱乐节目,放松放松。0、早晨AM:9:30一觉睡到自然醒的感觉是很爽的,九点半才起床,唉,是不是起点有点晚了!AM:9:40~…

  • OutputStreamWriter Writer PrintWriter「建议收藏」

    OutputStreamWriter Writer PrintWriter「建议收藏」OutputStreamWriter是字符流通向字节流的桥梁,可使用指定的charset将要写入流中的字符编码成字节。(即用字符流的方式写字节流)例如:InputStreamReaderisr=newInputStreamReader(newFileInputStream(FileDescriptor.in));  OutputStreamWriterosw=

  • VS2010过期密钥「建议收藏」

    VS2010过期密钥「建议收藏」VS2010 旗舰版可用Key:YCFHQ-9DWCY-DKV88-T2TMH-G7BHP

  • unity3d自学教程_3D技巧

    unity3d自学教程_3D技巧0.目录简要介绍基本概念视图菜单坐标系统资源元素脚本交互相机操作 1.简要介绍Unity3D软件是由UnityTechnologies公司提供的综合开发环境,主要面向游戏开发人员、虚拟现实设计师等,可用于创建诸如三维视频游戏、建筑可视化、实时三维动画等类型的多媒体内容,并支持这些内容在Windows、iOS、Android等多种平台的发布,功能非常强大。Unity3D

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号