oing9179 的笔记本儿

自定义任务触发器 - Spring Framework

Preface

这几天做开发时有个比较特别的需求:当前时间的分钟数在 {5, 15, 25, 35, 45, 55} 的时候触发某个事件。Spring 自带的触发器(包括 Cron)都没法满足这个需求,于是就只能自定义一个触发器了。

Trigger 接口

写个类实现 org.springframework.scheduling.Trigger,接口里唯一的一个方法 nextExecutionTime(TriggerContext): Date 需要返回一个 Date 类型的对象,表示下一次执行任务的时间。

1
2
3
4
5
6
class ExampleTaskTrigger : Trigger {
override fun nextExecutionTime(triggerContext: TriggerContext): Date {
// triggerContext 有3个方法可以分别用来获取到任务的计划执行时间、实际执行时间和执行完成的时间。
// 该 Trigger 被首次调用时,那3个方法的返回值都为 null。
}
}

nextExecutionTime 方法会在两种情况下调用:

  1. Spring 容器启动时
  2. 定时任务执行完成后

注册定时任务

参考下面的 Spring 配置文件。
ExampleClass 类没有继承任何类或实现任何方法,类内只有一个无参数taskMethod 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">

<bean id="exampleClassBean" class="com.example.ExampleClass"/>
<bean id="exampleTaskTrigger" class="com.example.ExampleTaskTrigger"/>

<task:scheduled-tasks>
<task:scheduled ref="exampleClassBean" method="taskMethod" trigger="exampleTaskTrigger"/>
</task:scheduled-tasks>

</beans>

配置完成后,Spring 就会询问 exampleTaskTrigger.nextExecutionTime(TriggerContext) 来决定什么时候执行 exampleClassBean.taskMethod()