Quarkus Extension for Spring Scheduling API
尽管 Quarkus 鼓励用户使用 regular Quarkus scheduler,但 Quarkus 提供了针对采用 spring-scheduled
扩展形式的 Spring Scheduled 的兼容层。
本指南说明 Quarkus 应用程序如何利用众所周知的 Spring Scheduled 注解,以配置和计划任务。
Solution
我们建议您遵循接下来的部分中的说明,按部就班地创建应用程序。然而,您可以直接跳到完成的示例。
克隆 Git 存储库: git clone {quickstarts-clone-url}
,或下载 {quickstarts-archive-url}[存档]。
解决方案位于 spring-scheduled-quickstart
directory。
Creating the Maven project
首先,我们需要一个新项目。使用以下命令创建一个新项目:
Unresolved directive in spring-scheduled.adoc - include::{includes}/devtools/create-app.adoc[]
此命令生成一个带有 spring-scheduled
扩展的 Maven 项目。
如果已经配置好你的 Quarkus 项目,则可以通过在项目基础目录中运行以下命令,将 spring-scheduled
扩展添加到你的项目中:
Unresolved directive in spring-scheduled.adoc - include::{includes}/devtools/extension-add.adoc[]
这会将以下内容添加到构建文件中:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-spring-scheduled</artifactId>
</dependency>
implementation("io.quarkus:quarkus-spring-scheduled")
Creating a scheduled job
在 org.acme.spring.scheduler
包中,使用以下内容创建 CounterBean
类:
package org.acme.spring.scheduler;
import org.springframework.scheduling.annotation.Scheduled;
import java.util.concurrent.atomic.AtomicInteger;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped (1)
public class CounterBean {
private AtomicInteger counter = new AtomicInteger();
public int get() { (2)
return counter.get();
}
@Scheduled(cron="*/5 * * * * ?") (3)
void cronJob() {
counter.incrementAndGet(); (4)
System.out.println("Cron expression hardcoded");
}
@Scheduled(cron = "{cron.expr}") (5)
void cronJobWithExpressionInConfig() {
counter.incrementAndGet();
System.out.println("Cron expression configured in application.properties");
}
@Scheduled(fixedRate = 1000) (6)
void jobAtFixedRate() {
counter.incrementAndGet();
System.out.println("Fixed Rate expression");
}
@Scheduled(fixedRateString = "${fixedRate.expr}") (7)
void jobAtFixedRateInConfig() {
counter.incrementAndGet();
System.out.println("Fixed Rate expression configured in application.properties");
}
}
<1> 在 _application_ 范围内声明 Bean。Spring 仅在 Bean 中检测 @Scheduled 注解。 <1> `get()` 方法允许获取当前值。 <1> 使用 Spring `@Scheduled` 注解并附带类似 cron 的表达式,指示 Quarkus 计划运行此方法。在本示例中,我们计划每天上午 10:15 执行一项任务。 <1> 代码非常简单。每天上午 10:15,计数器都会递增一次。 <1> 使用在 `application.properties` 中可配置的类似 cron 的表达式 `cron.expr` 定义一项作业。 <1> 定义一个方法,让其在固定的时间间隔内执行。时段以毫秒为单位表示。 <1> 使用在 `application.properties` 中可配置的 `fixedRate.expr` 定义一项作业,让其在固定的时间间隔内执行。
Updating the application configuration file
编辑 application.properties
文件并添加 cron.expr
和 fixedRate.expr
配置:
# The syntax used by Spring for cron expressions is the same as which is used by regular Quarkus scheduler.
cron.expr=*/5 * * * * ?
fixedRate.expr=1000
Creating the resource and the test
使用以下内容创建 CountResource
类:
package org.acme.spring.scheduler;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/count")
public class CountResource {
@Inject
CounterBean counter; (1)
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "count: " + counter.get(); (2)
}
}
<1> Inject the `CounterBean` <1> 发回当前计数器值
我们还需要更新测试。编辑 CountResourceTest
类以进行匹配:
package org.acme.spring.scheduler;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.containsString;
import org.junit.jupiter.api.Test;
import io.quarkus.test.junit.QuarkusTest;
@QuarkusTest
public class CountResourceTest {
@Test
public void testHelloEndpoint() {
given()
.when().get("/count")
.then()
.statusCode(200)
.body(containsString("count")); (1)
}
}
<1> 确保响应包含 `count`
Package and run the application
使用以下内容运行应用程序:
Unresolved directive in spring-scheduled.adoc - include::{includes}/devtools/dev.adoc[]
在另一个终端中,运行 curl localhost:8080/count
以检查计数器值。几秒钟后,重新运行 curl localhost:8080/count
以验证计数器已被增量。
观察控制台以验证已显示以下消息:- Cron expression hardcoded
- Cron expression configured in application.properties
- Fixed Rate expression
- Fixed Rate expression configured in application.properties`这些消息表明使用了 `@Scheduled
注释的方法执行已被触发。
和往常一样,可以使用以下命令打包应用程序:
Unresolved directive in spring-scheduled.adoc - include::{includes}/devtools/build.adoc[]
并使用 `java -jar target/quarkus-app/quarkus-run.jar`执行。
你还可以按如下方式生成本机可执行文件:
Unresolved directive in spring-scheduled.adoc - include::{includes}/devtools/build-native.adoc[]
Using Property Expressions
Quarkus 在 application.properties
文件中支持使用属性表达式,所以要使任务的配置外在化,你应该将属性存储在 application.properties
文件中,并分别使用 fixedRateString
、initialDelayString
参数。
请注意,此配置是构建时配置,属性表达式将在构建时解析。
Unsupported Spring Scheduled functionalities
Quarkus 当前仅支持 Spring @Scheduled 提供的部分功能,并计划更多功能。目前,fixedDelay
和 fixedDelayString
参数不受支持,换句话说,@Scheduled
方法始终独立执行。
Important Technical Note
请注意,Quarkus 中的 Spring 支持不会启动 Spring 应用程序上下文,也不会运行任何 Spring 基础设施类。Spring 类和注释仅用于读取元数据和/或用作用户代码方法返回类型或参数类型。这对最终用户意味着,添加任意 Spring 库不会产生任何影响。此外,Spring 基础设施类(例如 org.springframework.beans.factory.config.BeanPostProcessor
)不会被执行。
More Spring guides
Quarkus 还有更多 Spring 兼容性功能。请参阅以下指南以获取更多详情: