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)组成。

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 详解结构方程模型,路径分析方法有哪些_结构方程模型的数据要求

    详解结构方程模型,路径分析方法有哪些_结构方程模型的数据要求一、简介微生物群落研究逐渐从单一的群落结构研究转向分析群落与环境因素的关联互作机制研究当中,典型的环境因子分析方法有CCA/RDA、互作网络图、VPA分析等,这些分析能帮助我们逐一比较待选的环境因子与微生物群落数据间的关联性,细致挖掘对群落结构有影响的个别环境因子。需要注意到的是,环境对微生物群落的影响是间接的,例如:气温因素影响了植物的生长状态,植物的生长状态的变化影响土壤微生物的群落结构……

    2022年8月24日
    8
  • 如何解决Windows10系统空闲时间CPU占用高,风扇很响的问题?

    如何解决Windows10系统空闲时间CPU占用高,风扇很响的问题?说句心里话,对用惯了win7系统的我来说,Windows10系统是非常难用的,因为现如今的电脑几乎都不再有光驱,想要重装系统,必须网上下载或者拷贝进U盘里。但是,系统一般都很大,下载需要消耗很长时间,还不一定能用。所以,我一直强迫自己习惯使用Windows10系统,如今倒是渐渐习惯了,但其中有几个非常烦人的地方:一个是系统更新。我刚拿到电脑的时候,客服就跟我说,Windows10系统更新会导致电脑总是蓝屏。我问能不能阻止更新,但客服表示没办法,已经来不及了,现在就算禁止了也没用。果不其然,在..

    2022年10月20日
    4
  • 安装gcc5.4版本[通俗易懂]

    安装gcc5.4版本[通俗易懂]安装gcc5.4版本:https://blog.csdn.net/xie1xiao1jun/article/details/54378079?utm_source=blogxgwz9

    2022年5月26日
    45
  • eclipse离线安装svn插件使用教程_eclipse不显示svn插件

    eclipse离线安装svn插件使用教程_eclipse不显示svn插件【Android】Eclipsesvn插件安装说明   昨天心血来潮,因为总是有些小的测试文档修改了修改去,后来某天找代码又麻烦得很,想把本机上的所有代码管理起来,在网上度娘了下,决定在Eclipse中安装svn插件,来管理本地的源代码文档。现在附上一些安装步骤,后续的使用慢慢地摸索吧。一、安装环境:PC:windowEclipse:JunoServiceRelease

    2022年10月7日
    3
  • goland激活(在线激活)「建议收藏」

    goland激活(在线激活),https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月14日
    430
  • stat函数详解_stl函数

    stat函数详解_stl函数stat函数讲解表头文件:   #include            #include定义函数:   intstat(constchar*file_name,structstat*buf);函数说明:   通过文件名filename获取文件信息,并保存在buf所指的结构体stat中返回值:     执行成功则返回0,失败返回-1,错误代码存于er

    2022年8月21日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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