本指南将引导您完成使用 Spring 调度任务的步骤。
你将构建什么
您将构建一个应用程序,该程序通过使用 Spring Framework 的 @Scheduled 注解每五秒钟打印一次当前时间。
所需条件
-
大约15分钟
-
一个喜欢的文本编辑器或IDE
-
Java 17 或更高版本
如何完成本指南
与大多数 Spring 入门指南 一样,您可以从头开始并完成每个步骤,或者通过查看 此仓库 中的代码直接跳到解决方案。
要在本地环境中查看最终结果,您可以执行以下操作之一:
-
下载并解压本指南的源代码仓库
-
使用 Git 克隆仓库:
git clone https://github.com/spring-guides/gs-scheduling-tasks.git
-
Fork 该仓库,以便您可以通过提交拉取请求来请求对本指南的更改
从 Spring Initializr 开始
您可以使用这个预初始化项目,然后点击生成以下载一个 ZIP 文件。该项目已配置为适合本指南中的示例。
要手动初始化项目:
-
访问 https://start.spring.io。该服务会拉取应用程序所需的所有依赖项,并为您完成大部分设置工作。
-
选择 Gradle 或 Maven 以及您想要使用的语言。本指南假设您选择了 Java 和 Gradle。
-
点击 Generate。
-
下载生成的 ZIP 文件,这是一个根据您的选择配置好的应用程序存档。
如果您的 IDE 集成了 Spring Initializr,您可以直接在 IDE 中完成此过程。
启用调度
虽然可以将定时任务嵌入到 web 应用程序中,但更简单的方法(如本指南所示)是创建一个独立的应用程序。为此,将所有内容打包到一个可执行的 JAR 文件中,并通过 Java 的 main() 方法来驱动。以下代码片段(来自 src/main/java/com/example/schedulingtasks/SchedulingTasksApplication.java
)展示了应用程序类:
@SpringBootApplication
@EnableScheduling
public class SchedulingTasksApplication {
Spring Initializr 在我们的主类中添加了 @SpringBootApplication
注解。@SpringBootApplication
是一个便捷的注解,它添加了以下所有内容:
-
@Configuration
: 将该类标记为应用程序上下文的bean定义源。 -
@EnableAutoConfiguration
: Spring Boot 根据您添加的依赖项尝试自动配置您的 Spring 应用程序。 -
@ComponentScan
: 告诉 Spring 去查找其他组件、配置和服务。如果没有定义特定的包,递归扫描将从声明该注解的类所在的包开始。
此外,添加 @EnableScheduling
注解。该注解启用了 Spring 的定时任务执行功能。
创建计划任务
创建一个名为 src/main/java/com/example/schedulingtasks/ScheduledTasks.java
的新类:
@Component
public class ScheduledTasks {
private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
log.info("The time is now {}", dateFormat.format(new Date()));
}
}
Scheduled 注解 定义了特定方法的执行时间。
本示例使用了 [
fixedRate()
](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html#fixedRate(),它指定了方法调用之间的间隔,从每次调用的开始时间开始计算。其他选项包括 [cron()
](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html#cron() 和 [fixedDelay()
](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html#fixedDelay()。对于周期性任务,必须指定这三种选项中的一种,并且可以选择性地指定 [initialDelay()
](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html#initialDelay()。对于一次性任务,只需指定一个 initialDelay() 即可。
运行应用程序
现在,您应该能够通过执行 SchedulingTasksApplication
中的主方法来运行应用程序。您可以从 IDE 中运行该程序,也可以在项目根目录下执行以下 Gradle 命令:
./gradlew bootRun
这样做会启动应用程序,并且带有 @Scheduled 注解的方法会运行。您应该会看到类似于以下的日志消息:
20yy-mm-ddT07:23:01.665-04:00 INFO 19633 --- [ scheduling-1] c.e.schedulingtasks.ScheduledTasks : The time is now 07:23:01
20yy-mm-ddT07:23:06.663-04:00 INFO 19633 --- [ scheduling-1] c.e.schedulingtasks.ScheduledTasks : The time is now 07:23:06
20yy-mm-ddT07:23:11.663-04:00 INFO 19633 --- [ scheduling-1] c.e.schedulingtasks.ScheduledTasks : The time is now 07:23:11
此示例使用 [
fixedRate()
](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html#fixedRate() 调度,因此应用程序将无限期运行,直到您手动中断它。
使用 awaitility 依赖进行测试
为了正确测试您的应用程序,您可以使用 awaitility
库。自 Spring Boot 3.2 起,这是一个由 Boot 管理的依赖项。您可以在 src/test/java/com/example/schedulingtasks/ScheduledTasksTest.java
中创建新测试或查看现有测试:
@SpringBootTest
public class ScheduledTasksTest {
@SpyBean
ScheduledTasks tasks;
@Test
public void reportCurrentTime() {
await().atMost(Durations.TEN_SECONDS).untilAsserted(() -> {
verify(tasks, atLeast(2)).reportCurrentTime();
});
}
}
当您运行 ./gradlew clean build
任务时,此测试会自动执行。
构建应用程序
本节介绍了运行本指南的不同方式:
-
构建并执行 JAR 文件
-
使用 Cloud Native Buildpacks 构建并执行 Docker 容器
-
构建并执行原生镜像
-
使用 Cloud Native Buildpacks 构建并执行原生镜像容器
无论您选择如何运行应用程序,输出结果都应该是一样的。
要运行该应用程序,您可以将其打包为可执行的 jar 文件。./gradlew clean build
命令会将应用程序编译为可执行的 jar 文件。然后,您可以使用 java -jar build/libs/gs-scheduling-tasks-0.0.1-SNAPSHOT.jar
命令来运行该 jar 文件。
或者,如果您有一个可用的 Docker 环境,您可以直接使用 buildpacks 从 Maven 或 Gradle 插件创建 Docker 镜像。通过 Cloud Native Buildpacks,您可以创建可以在任何地方运行的 Docker 兼容镜像。Spring Boot 直接为 Maven 和 Gradle 提供了 buildpack 支持。这意味着您可以输入一条命令,并快速将合理的镜像推送到本地运行的 Docker 守护程序中。要使用 Cloud Native Buildpacks 创建 Docker 镜像,请运行 ./gradlew bootBuildImage
命令。在启用 Docker 环境的情况下,您可以使用 docker run docker.io/library/gs-scheduling-tasks:0.0.1-SNAPSHOT
命令来运行该应用程序。
原生镜像支持
Spring Boot 还支持编译为原生镜像,前提是您的机器上安装了 GraalVM 发行版。要使用 Native Build Tools 通过 Gradle 创建原生镜像,首先确保您的 Gradle 构建中包含一个 plugins
块,其中包含 org.graalvm.buildtools.native
。
plugins {
id 'org.graalvm.buildtools.native' version '0.9.28'
...
您可以运行 ./gradlew nativeCompile
命令来生成原生镜像。当构建完成后,您可以通过执行 build/native/nativeCompile/gs-scheduling-tasks
命令来运行代码,并且启动时间几乎瞬时。
您也可以使用 Buildpacks 创建原生镜像。通过运行 ./gradlew bootBuildImage
命令,您可以生成原生镜像。构建完成后,您可以使用 docker run docker.io/library/gs-scheduling-tasks:0.0.1-SNAPSHOT
命令启动应用程序。
总结
恭喜!您已成功创建了一个包含定时任务的应用程序。
另请参阅
以下指南可能也会有所帮助: