Quarkus Extension for Spring Scheduling API
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.
This guide explains how a Quarkus application can leverage the well known Spring Scheduled annotation to configure and schedule tasks.
Pré-requisitos
Para concluir este guia, você precisa:
-
Cerca de 15 minutos
-
Um IDE
-
JDK 17+ installed with
JAVA_HOME
configured appropriately -
Apache Maven 3.9.9
-
Opcionalmente, o Quarkus CLI se você quiser usá-lo
-
Opcionalmente, Mandrel ou GraalVM instalado e configurado apropriadamente se você quiser criar um executável nativo (ou Docker se você usar uma compilação de contêiner nativo)
-
Some familiarity with the Spring Web extension
Solução
Recomendamos que siga as instruções nas seções seguintes e crie a aplicação passo a passo. No entanto, você pode ir diretamente para o exemplo completo.
Clone o repositório Git: git clone https://github.com/quarkusio/quarkus-quickstarts.git
, ou baixe um arquivo.
The solution is located in the spring-scheduled-quickstart
directory.
Criar o projeto Maven
Primeiro, precisamos de um novo projeto. Crie um novo projeto com o seguinte comando:
Para usuários do Windows:
-
Se estiver usando cmd, (não use barra invertida '\' e coloque tudo na mesma linha)
-
Se estiver usando o Powershell, envolva os parâmetros '-D' entre aspas duplas, por exemplo, '"-DprojectArtifactId=spring-scheduler-quickstart"'
This command generates a Maven project with the spring-scheduled
extension.
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:
quarkus extension add spring-scheduled
./mvnw quarkus:add-extension -Dextensions='spring-scheduled'
./gradlew addExtension --extensions='spring-scheduled'
Isto irá adicionar o seguinte trecho no seu arquivo de build:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-spring-scheduled</artifactId>
</dependency>
implementation("io.quarkus:quarkus-spring-scheduled")
Criando um trabalho agendado
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 | O método get() permite obter o valor atual. |
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 | Defina um trabalho com uma expressão do tipo cron cron.expr que é configurável em 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 . |
Atualizando o arquivo de configuração da aplicação
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
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 | Injete o CounterBean |
2 | Envie de volta o valor atual do contador |
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 |
Empacote e execute a aplicação
Execute a aplicação com:
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
Em outro terminal, execute curl localhost:8080/count
para verificar o valor do contador. Após alguns segundos, execute novamente curl localhost:8080/count
para verificar se o contador foi incrementado.
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.
Como de costume, a aplicação pode ser empacotada utilizando:
quarkus build
./mvnw install
./gradlew build
E executada com java -jar target/quarkus-app/quarkus-run.jar
.
Também é possível gerar o executável nativo com:
quarkus build --native
./mvnw install -Dnative
./gradlew build -Dquarkus.native.enabled=true
Using Property Expressions
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 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
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.
Mais guias de Spring
O Quarkus possui mais funcionalidades compatíveis com o Spring. Para mais informações, consulte os seguintes guias: