Quarkus Extension for Spring Scheduling API
尽管 Quarkus 鼓励用户使用 regular Quarkus scheduler,但 Quarkus 提供了针对采用 spring-scheduled
扩展形式的 Spring Scheduled 的兼容层。
本指南说明 Quarkus 应用程序如何利用众所周知的 Spring Scheduled 注解,以配置和计划任务。
- Prerequisites
- Solution
- Creating the Maven project
- Creating a scheduled job
- Updating the application configuration file
- Creating the resource and the test
- Package and run the application
- Using Property Expressions
- Unsupported Spring Scheduled functionalities
- Important Technical Note
- More Spring guides
Solution
我们建议您遵循接下来的部分中的说明,按部就班地创建应用程序。然而,您可以直接跳到完成的示例。
克隆 Git 存储库: git clone $${quickstarts-base-url}.git
,或下载 $${quickstarts-base-url}/archive/main.zip[存档]。
解决方案位于 spring-scheduled-quickstart
directory。
Creating the Maven project
首先,我们需要一个新项目。使用以下命令创建一个新项目:
quarkus create app {create-app-group-id}:{create-app-artifact-id} \
--no-code
cd {create-app-artifact-id}
要创建一个 Gradle 项目,添加 --gradle
或 --gradle-kotlin-dsl
选项。
有关如何安装和使用 Quarkus CLI 的详细信息,请参见 Quarkus CLI 指南。
mvn {quarkus-platform-groupid}:quarkus-maven-plugin:{quarkus-version}:create \
-DprojectGroupId={create-app-group-id} \
-DprojectArtifactId={create-app-artifact-id} \
-DnoCode
cd {create-app-artifact-id}
要创建一个 Gradle 项目,添加 -DbuildTool=gradle
或 -DbuildTool=gradle-kotlin-dsl
选项。
适用于 Windows 用户:
-
如果使用 cmd,(不要使用反斜杠
\
,并将所有内容放在同一行上) -
如果使用 Powershell,将
-D
参数用双引号引起来,例如"-DprojectArtifactId={create-app-artifact-id}"
此命令生成一个带有 spring-scheduled
扩展的 Maven 项目。
如果已经配置好你的 Quarkus 项目,则可以通过在项目基础目录中运行以下命令,将 spring-scheduled
扩展添加到你的项目中:
quarkus extension add {add-extension-extensions}
./mvnw quarkus:add-extension -Dextensions='{add-extension-extensions}'
./gradlew addExtension --extensions='{add-extension-extensions}'
这会将以下内容添加到构建文件中:
<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 注解。 |
2 | get() 方法允许获取当前值。 |
3 | 使用 Spring @Scheduled 注解并附带类似 cron 的表达式,指示 Quarkus 计划运行此方法。在本示例中,我们计划每天上午 10:15 执行一项任务。 |
4 | 代码非常简单。每天上午 10:15,计数器都会递增一次。 |
5 | 使用在 application.properties 中可配置的类似 cron 的表达式 cron.expr 定义一项作业。 |
6 | 定义一个方法,让其在固定的时间间隔内执行。时段以毫秒为单位表示。 |
7 | 使用在 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 |
2 | 发回当前计数器值 |
我们还需要更新测试。编辑 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
使用以下内容运行应用程序:
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
在另一个终端中,运行 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
注释的方法执行已被触发。
和往常一样,可以使用以下命令打包应用程序:
quarkus build
./mvnw install
./gradlew build
并使用 `java -jar target/quarkus-app/quarkus-run.jar`执行。
你还可以按如下方式生成本机可执行文件:
quarkus build --native
./mvnw install -Dnative
./gradlew build -Dquarkus.native.enabled=true
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 兼容性功能。请参阅以下指南以获取更多详情: