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

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.

前提条件

このガイドを完成させるには、以下が必要です:

  • 約15分

  • IDE

  • JDK 11+ がインストールされ、 JAVA_HOME が適切に設定されていること

  • Apache Maven 3.8.1+

  • 使用したい場合、 Quarkus CLI

  • ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること

  • Some familiarity with the Spring Web extension

ソリューション

次のセクションで紹介する手順に沿って、ステップを踏んでアプリを作成することをお勧めします。ただし、完成した例にそのまま進んでも構いません。

Gitレポジトリをクローンするか git clone https://github.com/quarkusio/quarkus-quickstarts.gitアーカイブ をダウンロードします。

The solution is located in the spring-scheduled-quickstart directory.

Mavenプロジェクトの作成

まず、新しいプロジェクトが必要です。以下のコマンドで新規プロジェクトを作成します。

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

Gradleプロジェクトを作成するには、 --gradle または --gradle-kotlin-dsl オプションを追加します。

Quarkus CLIのインストール方法については、Quarkus CLIガイドをご参照ください。

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

Gradleプロジェクトを作成するには、 -DbuildTool=gradle または -DbuildTool=gradle-kotlin-dsl オプションを追加します。

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:

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

This will add the following to your build file:

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

スケジュールされたジョブの作成

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 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 the bean in the application scope. Spring only detects @Scheduled annotations in beans.
2 get() メソッドでは、現在の値を取得することができます。
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 application.properties で設定可能な`cron.expr` で cron のような式でジョブを定義します。
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.

アプリケーション設定ファイルの更新

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 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 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 が含まれていることを確認

アプリケーションをパッケージ化して実行する

Run the application with:

CLI
quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./gradlew --console=plain quarkusDev

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.

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.

いつものように、アプリケーションは以下の方法でパッケージ化されます。

CLI
quarkus build
Maven
./mvnw clean package
Gradle
./gradlew build

And executed using java -jar target/quarkus-app/quarkus-run.jar.

次のようにネイティブ実行可能ファイルを生成することもできます。

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

プロパティー式の使用

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.