Quartz如何根据cron表达式计算任务开始前发送通知的时间?

任务调度

任务的执行时间是cron表达式,使用quartz定时器生成任务
现在需要在每次任务开始前一定时间(例:1天、一周、15分钟)发送通知

在不改前端的情况下。有什么好的做法实现吗。

计算通知的cron,有点过于复杂,也没有找到工具可以使用

阅读 2.8k
avatarAI BotBETA

在Quartz中实现任务开始前发送通知的功能,通常的做法不是通过计算另一个Cron表达式来确定通知的时间,而是利用Quartz提供的触发器监听器(TriggerListener)或者任务监听器(JobListener)来实现。这些监听器允许你在触发器触发前或任务执行前执行自定义逻辑。

下面是一个简单的例子,展示了如何使用触发器监听器在任务开始前发送通知:

import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;

public class NotificationTriggerListener implements TriggerListener {

    @Override
    public String getName() {
        return "NotificationTriggerListener";
    }

    @Override
    public void triggerFired(Trigger.TriggeredBundle bundle) {
        // 当触发器触发时,执行此方法
        JobExecutionContext context = bundle.getJobExecutionContext();
        JobDetail jobDetail = context.getJobDetail();
        Trigger trigger = bundle.getTrigger();
        
        // 这里发送通知的逻辑
        sendNotification(jobDetail, trigger);
    }

    @Override
    public boolean isTriggerComplete(Trigger.CompletedExecutionInstruction triggerInstructionCode) {
        return true;
    }

    @Override
    public void triggerMisfired(Trigger.TriggeredBundle bundle) {
        // 当触发器误触发时执行
    }

    @Override
    public void triggerComplete(Trigger.CompletedExecutionInstruction triggerInstructionCode, JobExecutionContext context, CompletedExecutionException exception) {
        // 触发器完成时执行
    }

    private void sendNotification(JobDetail jobDetail, Trigger trigger) {
        // 这里编写发送通知的代码,例如发送邮件、消息队列等
        // 你可以根据jobDetail和trigger的信息来决定通知的内容
        // 例如,可以获取触发器下次的执行时间,并提前一定时间发送通知
    }

    // 其他方法可以留空或返回默认值
}

// 在Quartz Scheduler初始化时注册监听器
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.getListenerManager().addTriggerListener(new NotificationTriggerListener());

在上面的代码中,NotificationTriggerListener 类实现了 TriggerListener 接口,并重写了 triggerFired 方法。当触发器触发时,该方法会被调用,你可以在这个方法中编写发送通知的逻辑。你可以从 JobExecutionContext 对象中获取 JobDetailTrigger 的信息,然后根据这些信息来决定通知的内容。

注意,这里的 sendNotification 方法是一个占位符,你需要根据实际需求来实现发送通知的逻辑。例如,你可以使用邮件服务、消息队列或其他通信机制来发送通知。

另外,如果你想在任务开始前的一定时间发送通知,你可以在 sendNotification 方法中计算触发器下次的执行时间,然后提前相应的时间发送通知。这可以通过获取触发器的 getNextFireTime() 方法来实现。

最后,记得在Quartz Scheduler初始化时注册你的监听器,这样它才能正常工作。

这种方法不需要计算另一个Cron表达式,而是利用了Quartz的事件监听机制,使得代码更加清晰和可维护。

4 个回答

那就再写一个quartz定时任务,表达式设为之前的任务的前15/1天/1周...执行就可以了
现在AI助手很多,你直接让它们提供你需要时间的cron表达式就行了

Quartz的触发器还不能实现你的需求,但你可以自己解析cron表达式以获取到下一次执行的时间。
Spring提供的工具:

    final CronExpression cronExpression = CronExpression.parse("0 0/12 * * * ?");
    final LocalDateTime dateTime = cronExpression.next(LocalDateTime.now());

可以直接获取到cron表达式的下次执行时间,当你拿到这个时间后,就很容易可以实现你的需求

bing搜索的 https://www.matools.com/cron/

当前的解决方案是设置一个定时任务A——以两次任务A间隔时间与任务提前通知时间为条件,通过Quartz的CronExpression解析,拿到任务实际通知时间,生成对应的通知任务放到执行队列中。

CronExpression务必使用Quartz包中。spring的CronExpression类试用于unix的cron规则,quartz的cron规则会不太一样

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏