quartz 2.3.1源码分析一:创建JobDetail(JobBuilder详解)

上一篇文章我记录了自己封装的QuartzUtil工具类,同时写了一个quartz骨架项目,以便大家理解使用。点击传送门进入。
QuartzManager接口文档

正文开始

一、创建定时任务

这是QuartzUtil中创建定时任务的方法。之后的部分将通过这个方法浅析quartz在创建Job时是怎么一步步实现的。

/**
 * 
 * 在创建任务时未设置jobGroup和triggerGroup,Job创建后其均为默认值:DEFAULT,
 * 因此新创建的任务的jobName和triggerName,均不能与之前任务的重复.
 *
 * @param jobName     任务名
 * @param triggerName 触发器名
 * @param description 对该任务的秒数(非必须)
 * @param jobClass    要执行的任务
 * @param cron        cron表达式
 * @return true:创建Job成功,false:创建Job失败
 */
public static <T extends Job> boolean addJob(String jobName, String triggerName, String description,
                                             Class<T> jobClass, String cron) {
    try {
        JobDetail jobDetail = JobBuilder.newJob(jobClass)
                .withIdentity(jobName)
                .withDescription(description)
//              .usingJobData("param1", "将参数")
//              .usingJobData("param2", "传递到JOB任务中使用")
                .build();

        CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                .withIdentity(triggerName)
                .startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule(cron))
                .build();

        scheduler.scheduleJob(jobDetail, cronTrigger);

        if (!scheduler.isShutdown()) {
            scheduler.start();
        }
        return scheduler.isStarted();
    } catch (Exception e) {
        throw new CustomException(Code.EXECUTION_ERROR);
    }
}

二、创建JobDetail(JobBuilder详解)

首先介绍一下JobBuilder,他是用来实例化一个定时任务的。在quartz中这个定时任务就是JobDetail。当然JobDetail是一个接口,真正的实现类是JobDetailImpl,而在这个JobDetailImpl中保存的就是定时任务的相关信息。

(1) JobBuilder.newJob()

/**
 * 创建用于定义JobDetail的JobBuilder,并设置需要定时执行的任务类。
 * 
 * @param jobClass 需要定时执行的任务类,该类需要实现Job接口
 * @return a new JobBuilder
 */
public static JobBuilder newJob(Class <? extends Job> jobClass) {
    JobBuilder b = new JobBuilder();
    b.ofType(jobClass);  //设置将要执行的Job
    return b;
}

(2) JobBuilder.ofType()

/**
 * 设置在触发与此JobDetail关联的触发器时,将实例化并执行的类。
 * 
 * @param jobClazz a class implementing the Job interface.
 * @return the updated JobBuilder
 */
public JobBuilder ofType(Class <? extends Job> jobClazz) {
    this.jobClass = jobClazz;
    return this;
}

(3) JobBuilder.withIdentity()

/**
 * 使用给定的任务名称和默认的任务组名来创建JobKey,JobKey是定时任务JobDetail的标志。
 * 如果在JobBuilder上没有设置任何“withIdentity”方法,则将生成一个随机的、惟一的JobKey。
 *
 * @param name 定时任务名称
 * @return the updated JobBuilder
 */
public JobBuilder withIdentity(String name) {
    key = new JobKey(name, null);
    return this;
}  

withIdentity还有两个重载的方法,如下所示:

public JobBuilder withIdentity(String name, String group) {
    key = new JobKey(name, group);
    return this;
}

public JobBuilder withIdentity(JobKey jobKey) {
    this.key = jobKey;
    return this;
}

现在就一清二楚,withIdentity()方法的作用就是生成JobKey,赋值给JobBuilder的属性key。
接下来看一下,JobKey是如何生成的。

(4) JobKey

JobKey继承自Key,他提供两个构造方法,作用均为调用父类的构造方,另外两个静态方法也是类似的作用。

JobKey是JobDetail的唯一标识,他由任务名称(name)和任务组名称(group)组成,并且name在group中必须是惟一的。如果只指定了name,那么将使用默认的组名称(DEFAULT)来创建JobKey。

public final class JobKey extends Key<JobKey> {
    private static final long serialVersionUID = -6073883950062574010L;
    
    public JobKey(String name) {
        super(name, null);
    }
    public JobKey(String name, String group) {
        super(name, group);
    }

    public static JobKey jobKey(String name) {
        return new JobKey(name, null);
    }
    public static JobKey jobKey(String name, String group) {
        return new JobKey(name, group);
    }
}

(5) Key

Key是quartz中用于标识JobDetail和Trigger的对象。他有两个子类,一个是JobKey,另一个是TriggerKey,分别是JobDetail和Trigger的唯一标识。TriggerKey与JobKey基本没有区别,在下一篇文章中将会讲到TriggerKey的相关代码。

public class Key<T>  implements Serializable, Comparable<Key<T>> {
    private static final long serialVersionUID = -7141167957642391350L;
    
    //任务组默认名称
    public static final String DEFAULT_GROUP = "DEFAULT";
    //任务名
    private final String name;
    //任务组名
    private final String group;
    
    /**
     * name等于null时,抛出IllegalArgumentException。
     * name、group不为null时,使用给定的name和group创建Key。
     * group等于null时,使用name和默认任务组名'DEFAULT'创建Key。
     * 
     * @param name 任务名称
     * @param group 任务组名称
     */
    public Key(String name, String group) {
        if(name == null)
            throw new IllegalArgumentException("Name cannot be null.");
        this.name = name;
        if(group != null)
            this.group = group;
        else
            this.group = DEFAULT_GROUP;
    }

    public String getName() {
        return name;
    }

    public String getGroup() {
        return group;
    }
    
    //...省略类中其他方法:toString()、hashCode()、equals()、compareTo()、createUniqueName()
}

(6) JobBuilder.withDescription()

这个方法很简单就是用来给这个定时任务增加一个描述的。具体如下:

/**
 * 给任务设置一个有意义的描述
 * 
 * @param jobDescription 对任务的描述
 * @return the updated JobBuilder
 */
public JobBuilder withDescription(String jobDescription) {
    this.description = jobDescription;
    return this;
}

(7) JobBuilder.usingJobData()

这个方法的作用是我们可以通过键值对的方式将一些参数传到定时任务中,在定时任务中使用。

/**
 * 将给定的键-值对添加到JobDetail的JobDataMap
 * 
 * @return the updated JobBuilder
 * @see JobDetail#getJobDataMap()
 */
public JobBuilder usingJobData(String dataKey, String value) {
    jobDataMap.put(dataKey, value);
    return this;
}

(8) JobBuilder.build()

该方法就是实例化一个JobDetailImpl,然后将JobBuilder中的参数设置的JobDetailImpl中返回。

/**
 * 生成此JobBuilder定义的JobDetail实例
 *
 * @return the defined JobDetail.
 */
public JobDetail build() {

    JobDetailImpl job = new JobDetailImpl();
    
    job.setJobClass(jobClass);
    job.setDescription(description);
    if(key == null)
        key = new JobKey(Key.createUniqueName(null), null);
    job.setKey(key); 
    job.setDurability(durability);
    job.setRequestsRecovery(shouldRecover);
    
    if(!jobDataMap.isEmpty())
        job.setJobDataMap(jobDataMap);
    
    return job;
}

三、总结

(1) JobDetail

JobDetail是用来表达给定Job的详细属性信息的,作者的原话是:“Conveys the detail properties of a given Job instance.”,
JobDetail是一个接口,只有一个实现类JobDetailImpl,这是真正保存Job详细属性的类。在JobDetailImpl中主要有一下参数

参数类型默认值说明
nameString任务名称
groupStringScheduler.DEFAULT_GROUP = “DEFAULT”任务组名称
descriptionString任务描述
jobClassClass<? extends Job>真正需要执行的Job任务类
jobDataMapJobDataMap实现了Map接口,用于保存需要传递给Job的参数信息
durabilitybooleanfalse当没有trigger与Job关联时,是否需要保存Job
shouldRecoverbooleanfalse如果遇到“恢复”或“故障转移”情况,Scheduler是否应重新执行Job
keyJobKeyJobDetail的唯一标识,他由任务名称(name)和任务组名称(group)组成

(1) JobBuilder

JobBuilder采用build模式,用于实例化一个JobDetail。
JobBuilder的属性与JobDetail一模一样(除了没有name和group),当我们使用JobBuild的其他方法时都是将Job详细信息先保存到JobBuilder中,最后调用build方法时,new一个JobDetailImpl,然后将保存的参数都设置到JobDetailImpl中,然后返回。

四、GitHub

https://github.com/frost-2/QuartzManager

五、声明

本人会经常更新博客,并在文章附上更新时间! 转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weipinggg/article/details/108799682
欢迎大家关注我的公众号:frost2

  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
org.quartz-scheduler:quartz:2.3.2是一个Maven坐标,用于引入Quartz任务调度框架的相关依赖。你可以在你的项目中的pom.xml文件中添加如下依赖来引入Quartz 2.3.2版本: <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version> </dependency> 这个坐标代表了Quartz框架的版本号为2.3.2,可以通过Maven自动下载相关的jar包。 如果你想查看在你的项目中使用了org.quartz-scheduler:quartz:2.3.2版本后的依赖树,你可以使用命令"mvn dependency:tree"来查看。这个命令会列出项目的所有依赖关系,包括间接依赖。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [org.quartz](https://blog.csdn.net/qq_40144701/article/details/112540359)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [quartz-2.3.2-API文档-中文版.zip](https://download.csdn.net/download/qq_36462452/85549591)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [因为org.quartz-scheduler-quartz定时任务引入版本过高导致项目启动报错问题](https://blog.csdn.net/chengzhan9657/article/details/100839563)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值