quartz 2.3.1源码分析二:创建CronTrigger(TriggerBuilder详解)

前文

一、创建Trigger

TriggerBuilder是用来实例化Trigger的。他与JobBuilder在整体结构或者说设计风格上可以说是一模一样的,同样采用Builder模式。

QuartzUtil中使用TriggerBuilder创建一个Trigger,如下所示:

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

(1) TriggerBuilder.newTrigger()

调用自己的无参数构造函数,没什么可说的。

/**
 * 创建一个新的TriggerBuilder,用它来定义触发器的规范。
 * 
 * @return the new TriggerBuilder
 */
public static TriggerBuilder<Trigger> newTrigger() {
    return new TriggerBuilder<Trigger>();
}

(2) TriggerBuilder.withIdentity()

/**
 * 使用给定的触发器名称和默认的触发器组名称(DEFAULT)创建Trigger的唯一标识TriggerKey
 * 
 * <p>If none of the 'withIdentity' methods are set on the TriggerBuilder,
 * then a random, unique TriggerKey will be generated.</p>
 * 
 * @param name 触发器名称
 * @return the updated TriggerBuilder
 */
public TriggerBuilder<T> withIdentity(String name) {
    key = new TriggerKey(name, null);
    return this;
}  

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

public TriggerBuilder<T> withIdentity(String name, String group) {
    key = new TriggerKey(name, group);
    return this;
}
public TriggerBuilder<T> withIdentity(TriggerKey triggerKey) {
    this.key = triggerKey;
    return this;
}

如果看过第一篇文章,你就会发现TriggerBuilder和JobBuilder的withIdentity()方法非常非常的相似,甚至这两篇文章也非常相似。他们区别是TriggerBuilder生成Trigger的唯一标识TriggerKey,暂时保存在TriggerBuilder中,而JobBuilder是生成JobDetail的唯一标识JobKey,暂时保存在JobBuilder中。

(3) TriggerKey

其中JobKey和TriggerKey真的可以说是一模一样,这个上一篇文章中也有提到,他们都Key的子类。除了参数名其他都一模一样,只不过一个用来标识JobDetail,一个用来标识Trigger。对比下上一篇文章中的JobKey即可发现:

public final class TriggerKey extends Key<TriggerKey> {
  
    private static final long serialVersionUID = 8070357886703449660L;

    public TriggerKey(String name) {
        super(name, null);
    }

    public TriggerKey(String name, String group) {
        super(name, group);
    }

    public static TriggerKey triggerKey(String name) {
        return new TriggerKey(name, null);
    }
    
    public static TriggerKey triggerKey(String name, String group) {
        return new TriggerKey(name, group);
    }
    
}

(4) TriggerBuilder.startNow()

设置Trigger从当前时刻开始执行。

public TriggerBuilder<T> startNow() {
    this.startTime = new Date();
    return this;
}

与startNow相似功能的方法还有startAt(),endAt(),代码如下:

//设备触发器从传入的triggerStartTime开始执行。
public TriggerBuilder<T> startAt(Date triggerStartTime) {
    this.startTime = triggerStartTime;
    return this;
}

//设备触发器执行到传入的triggerStartTime后结束执行。
public TriggerBuilder<T> endAt(Date triggerEndTime) {
    this.endTime = triggerEndTime;
    return this;
}

唯一需要注意的是当调用startAt()方法时传入的时间早于cron表达式设置的时间,则将会触发一次,但不管cron表达式是否会会多次执行,都只会触发一次。例如,cron表达式为:0 0 12 * * ?,即每天12点执行一次,而startAt设置的时间是三天前,那么创建定时任务后只会触发一次,而不是三次。

(4) TriggerBuilder.withSchedule()

这个方法用于设置ScheduleBuilder,而ScheduleBuilder在负责真正实例化出一个Trigger。之所以这么做是因为ScheduleBuilder接口有四个实现类,我们需要哪种Trigger,那么在withSchedule中就传入哪种Trigger对应的ScheduleBuilder。

我们这是使用的ScheduleBuilder为CronScheduleBuilder,CronScheduleBuilder可以创建一个基于Cron表达式的Trigger。这也是使用最多、功能最强大的Trigger。

CronScheduleBuilder.cronSchedule(cron)

public static CronScheduleBuilder cronSchedule(String cronExpression) {
    try {
        return cronSchedule(new CronExpression(cronExpression));
    } catch (ParseException e) {
        // all methods of construction ensure the expression is valid by
        // this point...
        throw new RuntimeException("CronExpression '" + cronExpression
                                   + "' is invalid.", e);
    }
}

TriggerBuilder.withSchedule()

public <SBT extends T> TriggerBuilder<SBT> withSchedule(ScheduleBuilder<SBT> schedBuilder) {
    this.scheduleBuilder = schedBuilder;
    return (TriggerBuilder<SBT>) this;
}

(5) TriggerBuilder.build()

build方法使用withSchedule()方法设置的ScheduleBuilder实例化一个MutableTrigger。上面我们说ScheduleBuilder有四个实现类,那自然会产生四种Trigger,而这四个Trigger都是MutableTrigger的子类。其实这里就是多态而已——父类的引用指向子类的示例。网上看到有人说这里是开闭原则(OCP),嗯,也能这么理解吧。

public T build() {

    if(scheduleBuilder == null)
        scheduleBuilder = SimpleScheduleBuilder.simpleSchedule();
    MutableTrigger trig = scheduleBuilder.build();

    trig.setCalendarName(calendarName);
    trig.setDescription(description);
    trig.setStartTime(startTime);
    trig.setEndTime(endTime);
    if(key == null)
        key = new TriggerKey(Key.createUniqueName(null), null);
    trig.setKey(key); 
    if(jobKey != null)
        trig.setJobKey(jobKey);
    trig.setPriority(priority);

    if(!jobDataMap.isEmpty())
        trig.setJobDataMap(jobDataMap);

    return (T) trig;
}

二、GitHub

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

三、声明

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值