Quarkus Extension for Spring Scheduling API
尽管 Quarkus 鼓励用户使用 regular Quarkus scheduler,但 Quarkus 提供了针对采用 spring-scheduled
扩展形式的 Spring Scheduled 的兼容层。
While users are encouraged to use regular Quarkus scheduler, Quarkus provides a compatibility layer for Spring Scheduled in the form of the spring-scheduled
extension.
本指南说明 Quarkus 应用程序如何利用众所周知的 Spring Scheduled 注解,以配置和计划任务。
This guide explains how a Quarkus application can leverage the well known Spring Scheduled annotation to configure and schedule tasks.
Prerequisites
include::{includes}/prerequisites.adoc[]* 熟悉 Spring Web 扩展
Unresolved directive in spring-scheduled.adoc - include::{includes}/prerequisites.adoc[] * Some familiarity with the Spring Web extension
Solution
我们建议您遵循接下来的部分中的说明,按部就班地创建应用程序。然而,您可以直接跳到完成的示例。
We recommend that you follow the instructions in the next sections and create the application step by step. However, you can go right to the completed example.
克隆 Git 存储库: git clone {quickstarts-clone-url}
,或下载 {quickstarts-archive-url}[存档]。
Clone the Git repository: git clone {quickstarts-clone-url}
, or download an {quickstarts-archive-url}[archive].
解决方案位于 spring-scheduled-quickstart
directory。
The solution is located in the spring-scheduled-quickstart
directory.
Creating the Maven project
首先,我们需要一个新项目。使用以下命令创建一个新项目:
First, we need a new project. Create a new project with the following command:
Unresolved directive in spring-scheduled.adoc - include::{includes}/devtools/create-app.adoc[]
此命令生成一个带有 spring-scheduled
扩展的 Maven 项目。
This command generates a Maven project with the spring-scheduled
extension.
如果已经配置好你的 Quarkus 项目,则可以通过在项目基础目录中运行以下命令,将 spring-scheduled
扩展添加到你的项目中:
If you already have your Quarkus project configured, you can add the spring-scheduled
extension
to your project by running the following command in your project base directory:
Unresolved directive in spring-scheduled.adoc - include::{includes}/devtools/extension-add.adoc[]
这会将以下内容添加到构建文件中:
This will add the following to your build file:
<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
类:
In the org.acme.spring.scheduler
package, create the CounterBean
class, with the following content:
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 | Declare the bean in the application scope. Spring only detects @Scheduled annotations in beans. |
2 | The get() method allows retrieving the current value. |
3 | Use the Spring @Scheduled annotation with a cron-like expression to instruct Quarkus to schedule this method run. In this example we’re scheduling a task to be executed at 10:15am every day. |
4 | The code is pretty straightforward. Every day at 10:15am, the counter is incremented. |
5 | Define a job with a cron-like expression cron.expr which is configurable in application.properties . |
6 | Define a method to be executed at a fixed interval of time. The period is expressed in milliseconds. |
7 | Define a job to be executed at a fixed interval of time fixedRate.expr which is configurable in application.properties . |
Updating the application configuration file
编辑 application.properties
文件并添加 cron.expr
和 fixedRate.expr
配置:
Edit the application.properties
file and add the cron.expr
and the fixedRate.expr
configuration:
# 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
类:
Create the CountResource
class with the following content:
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 | Send back the current counter value |
我们还需要更新测试。编辑 CountResourceTest
类以进行匹配:
We also need to update the tests. Edit the CountResourceTest
class to match:
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 | Ensure that the response contains count |
Package and run the application
使用以下内容运行应用程序:
Run the application with:
Unresolved directive in spring-scheduled.adoc - include::{includes}/devtools/dev.adoc[]
在另一个终端中,运行 curl localhost:8080/count
以检查计数器值。几秒钟后,重新运行 curl localhost:8080/count
以验证计数器已被增量。
In another terminal, run curl localhost:8080/count
to check the counter value.
After a few seconds, re-run curl localhost:8080/count
to verify the counter has been incremented.
观察控制台以验证已显示以下消息:- Cron expression hardcoded
- Cron expression configured in application.properties
- Fixed Rate expression
- Fixed Rate expression configured in application.properties`这些消息表明使用了 `@Scheduled
注释的方法执行已被触发。
Observe the console to verify that the following messages has been displayed:
- Cron expression hardcoded
- Cron expression configured in application.properties
- Fixed Rate expression
- Fixed Rate expression configured in application.properties
These messages indicate that the executions of methods annotated with @Scheduled
have been triggered.
和往常一样,可以使用以下命令打包应用程序:
As usual, the application can be packaged using:
Unresolved directive in spring-scheduled.adoc - include::{includes}/devtools/build.adoc[]
并使用 `java -jar target/quarkus-app/quarkus-run.jar`执行。
And executed using java -jar target/quarkus-app/quarkus-run.jar
.
你还可以按如下方式生成本机可执行文件:
You can also generate the native executable with:
Unresolved directive in spring-scheduled.adoc - include::{includes}/devtools/build-native.adoc[]
Using Property Expressions
Quarkus 在 application.properties
文件中支持使用属性表达式,所以要使任务的配置外在化,你应该将属性存储在 application.properties
文件中,并分别使用 fixedRateString
、initialDelayString
参数。
Quarkus supports the use of property expressions in the application.properties
file so to externalize the configuration of the tasks you should store the properties in the application.properties
file and use the
fixedRateString
, initialDelayString
params respectively.
请注意,此配置是构建时配置,属性表达式将在构建时解析。
Note that this configuration is a build time configuration, the property expression will be resolved at build time.
Unsupported Spring Scheduled functionalities
Quarkus 当前仅支持 Spring @Scheduled 提供的部分功能,并计划更多功能。目前,fixedDelay
和 fixedDelayString
参数不受支持,换句话说,@Scheduled
方法始终独立执行。
Quarkus currently only supports a subset of the functionalities that Spring @Scheduled provides with more features being planned.
Currently, the fixedDelay
and fixedDelayString
parameters are not supported, in other words, @Scheduled
methods are always executed independently.
Important Technical Note
请注意,Quarkus 中的 Spring 支持不会启动 Spring 应用程序上下文,也不会运行任何 Spring 基础设施类。Spring 类和注释仅用于读取元数据和/或用作用户代码方法返回类型或参数类型。这对最终用户意味着,添加任意 Spring 库不会产生任何影响。此外,Spring 基础设施类(例如 org.springframework.beans.factory.config.BeanPostProcessor
)不会被执行。
Please note that the Spring support in Quarkus does not start a Spring Application Context nor are any Spring infrastructure classes run.
Spring classes and annotations are only used for reading metadata and / or are used as user code method return types or parameter types.
What that means for end users, is that adding arbitrary Spring libraries will not have any effect. Moreover, Spring infrastructure
classes (like org.springframework.beans.factory.config.BeanPostProcessor
for example) will not be executed.
More Spring guides
Quarkus 还有更多 Spring 兼容性功能。请参阅以下指南以获取更多详情:
Quarkus has more Spring compatibility features. See the following guides for more details: