The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

Extensão do Quarkus para a API de agendamento do Spring

Embora os usuários sejam incentivados a usar o agendador regular do Quarkus , o Quarkus fornece uma camada de compatibilidade para o Spring Scheduled na forma da extensão spring-scheduled .

Este guia explica como uma aplicação Quarkus pode utilizar a conhecida anotação Spring Scheduled para configurar e agendar tarefas.

Pré-requisitos

Para concluir este guia, você precisa:

  • Cerca de 15 minutos

  • Um IDE

  • JDK 11+ instalado com 'JAVA_HOME' configurado adequadamente

  • Apache Maven 3.8.6

  • 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)

  • Alguma familiaridade com a extensão Spring Web

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:

CLI
quarkus create app org.acme:spring-scheduler-quickstart \
    --stream=2.16 \
    --extension='resteasy-reactive,spring-scheduled' \
    --no-code
cd spring-scheduler-quickstart

Para criar um projeto Gradle, adicione a opção --gradle ou --gradle-kotlin-dsl.

For more information about how to install the Quarkus CLI and use it, please refer to the Quarkus CLI guide.

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:2.16.12.Final:create \
    -DplatformVersion=2.16 \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=spring-scheduler-quickstart \
    -Dextensions='resteasy-reactive,spring-scheduled' \
    -DnoCode
cd spring-scheduler-quickstart

Para criar um projeto Gradle, adicione a opção '-DbuildTool=gradle' ou '-DbuildTool=gradle-kotlin-dsl'.

Esse comando gera um projeto Maven com a extensão spring-scheduled .

Se já tiver o projeto Quarkus configurado, pode adicionar a extensão spring-scheduled ao seu projeto executando o seguinte comando no diretório base do projeto:

CLI
quarkus extension add 'spring-scheduled'
Maven
./mvnw quarkus:add-extension -Dextensions='spring-scheduled'
Gradle
./gradlew addExtension --extensions='spring-scheduled'

Isto irá adicionar o seguinte trecho no seu arquivo de build:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-spring-scheduled</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-spring-scheduled")

Criando um trabalho agendado

No pacote org.acme.spring.scheduler , crie a classe CounterBean , com o seguinte conteúdo:

package org.acme.spring.scheduler;

import org.springframework.scheduling.annotation.Scheduled;

import java.util.concurrent.atomic.AtomicInteger;
import javax.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 o bean no application scope . O Spring só detecta anotações @Scheduled em beans.
2 O método get() permite obter o valor atual.
3 Use a anotação @Scheduled do Spring com uma expressão no estilo cron para instruir o Quarkus a agendar a execução desse método. Neste exemplo, estamos agendando uma tarefa para ser executada às 10h15 todos os dias.
4 O código é bastante direto. Todos os dias, às 10h15, o contador é incrementado.
5 Defina um trabalho com uma expressão do tipo cron cron.expr que é configurável em application.properties.
6 Defina um método a ser executado em um intervalo de tempo fixo. O período é expresso em milissegundos.
7 Defina um job a ser executado em um intervalo fixo de tempo fixedRate.expr que é configurável em application.properties .

Atualizando o arquivo de configuração da aplicação

Edite o arquivo application.properties e adicione as configurações cron.expr e 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

Criar o recurso e o teste

Crie a classe CountResource com o seguinte conteúdo:

package org.acme.spring.scheduler;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.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

Também precisamos atualizar os testes. Edite a classe CountResourceTest para corresponder:

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 Certifique-se de que a resposta contenha count

Empacote e execute a aplicação

Execute a aplicação com:

CLI
quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./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 o console para verificar se as seguintes mensagens foram exibidas: - Cron expression hardcoded - Cron expression configured in application.properties - Fixed Rate expression - Fixed Rate expression configured in application.properties Essas mensagens indicam que as execuções dos métodos anotados com @Scheduled foram acionadas.

Como de costume, a aplicação pode ser empacotada utilizando:

CLI
quarkus build
Maven
./mvnw install
Gradle
./gradlew build

E executada com java -jar target/quarkus-app/quarkus-run.jar.

Também é possível gerar o executável nativo com:

CLI
quarkus build --native
Maven
./mvnw install -Dnative
Gradle
./gradlew build -Dquarkus.package.type=native

Usando expressões de propriedade

O Quarkus suporta o uso de expressões de propriedade no arquivo application.properties , portanto, para externalizar a configuração das tarefas, você deve armazenar as propriedades no arquivo application.properties e usar os parâmetros fixedRateString , initialDelayString respectivamente.

Observe que essa configuração é uma configuração de tempo de compilação; a expressão da propriedade será resolvida no tempo de compilação.

Funcionalidades do Spring Scheduled não suportadas

Atualmente, o Quarkus oferece suporte apenas a um subconjunto das funcionalidades pelo @Scheduled do Spring, com mais recursos sendo planejados. Atualmente, os parâmetros fixedDelay e fixedDelayString não são suportados, em outras palavras, os métodos anotados com @Scheduled são sempre executados de forma independente.

Nota técnica importante

Observe que o suporte ao Spring no Quarkus não inicia um Application Context do Spring, nem executa nenhuma classe de infraestrutura do Spring. As classes e anotações do Spring são usadas apenas para leitura de metadados e/ou como tipos de retorno de métodos ou tipos de parâmetros no código do usuário. Isso significa que, para os usuários finais, adicionar bibliotecas arbitrárias do Spring não terá nenhum efeito. Além disso, classes de infraestrutura do Spring (como org.springframework.beans.factory.config.BeanPostProcessor , por exemplo) não serão executadas.