Учебные материалы

Выполнение задач по расписанию

Этот урок освещает пошаговое создание задач по расписанию с использованием Spring.

Что вы создадите

Вы создадите приложение, которое будет печатать текущее время каждые пять секунд при помощи использования Spring-аннотации @Scheduled.

Что вам потребуется

  • Примерно 15 минут свободного времени
  • Любимый текстовый редактор или IDE
  • JDK 6 и выше
  • Gradle 1.11+ или Maven 3.0+
  • Вы также можете импортировать код этого урока, а также просматривать web-страницы прямо из Spring Tool Suite (STS), собственно как и работать дальше из него.

Как проходить этот урок

Как и большинство уроков по Spring, вы можете начать с нуля и выполнять каждый шаг, либо пропустить базовые шаги, которые вам уже знакомы. В любом случае, вы в конечном итоге получите рабочий код.

Чтобы начать с нуля, перейдите в Настройка проекта.

Чтобы пропустить базовые шаги, выполните следующее:

Когда вы закончите, можете сравнить получившийся результат с образцом в gs-scheduling-tasks/complete.

Настройка проекта

Для начала вам необходимо настроить базовый скрипт сборки. Вы можете использовать любую систему сборки, которая вам нравится для сборки проетов Spring, но в этом уроке рассмотрим код для работы с Gradle и Maven. Если вы не знакомы ни с одним из них, ознакомьтесь с соответсвующими уроками Сборка Java-проекта с использованием Gradle или Сборка Java-проекта с использованием Maven.

Создание структуры каталогов

В выбранном вами каталоге проекта создайте следующую структуру каталогов; к примеру, командой mkdir -p src/main/java/hello для *nix систем:

└── src
    └── main
        └── java
            └── hello

Создание файла сборки Gradle

Ниже представлен начальный файл сборки Gradle. Файл pom.xml находится здесь. Если вы используете Spring Tool Suite (STS), то можете импортировать урок прямо из него.

Если вы посмотрите на pom.xml, вы найдете, что указана версия для maven-compiler-plugin. В общем, это не рекомендуется делать. В данном случае он предназначен для решения проблем с нашей CI системы, которая по умолчанию имеет старую(до Java 5) версию этого плагина.

build.gradle

buildscript {
    repositories {
        maven { url "http://repo.spring.io/libs-release" }
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.6.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'

jar {
    baseName = 'gs-scheduling-tasks'
    version =  '0.1.0'
}

repositories {
    mavenLocal()
    mavenCentral()
    maven { url "http://repo.spring.io/libs-release" }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter")
    testCompile("junit:junit")
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.11'
}

Spring Boot gradle plugin предоставляет множество удобных возможностей:

  • Он собирает все jar'ы в classpath и собирает единое, исполняемое "über-jar", что делает более удобным выполнение и доставку вашего сервиса
  • Он ищет public static void main() метод, как признак исполняемого класса
  • Он предоставляет встроенное разрешение зависимостей, с определенными номерами версий для соответсвующих Spring Boot зависимостей. Вы можете переопределить на любые версии, какие захотите, но он будет по умолчанию для Boot выбранным набором версий

Создание задачи по расписанию

Теперь, когда вы настроили проект и систему сборки, вы можете создать вашу задачу по расписанию.

src/main/java/hello/ScheduledTasks.java

package hello;

import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

@EnableScheduling
public class ScheduledTasks {

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() {
        System.out.println("The time is now " + dateFormat.format(new Date()));
    }
}

Ключевыми компонентами, отвечающими за создание задач по расписанию, являются аннотации @EnableScheduling и @Scheduled.

@EnableScheduling гарантирует, что фоновые задачи создадуться. Без неё ничего не получится.

Используя @Scheduled, вы настраиваете, когда конкретный метод будет запущен. В этом примере используется fixedRate, который определяет интервал между вызовами метода, начиная с момента начала работы каждого из вызовов этого метода. Есть и другие параметры, например, fixedDelay, который определяет интервал между вызовами, начиная с момента окончания работы каждого из вызовов метода. Вы можете также использовать @Scheduled(cron=". . .") выражения для более конкретной установки расписания.

Это приложение не использует @EnableAutoConfiguration, как во многих других учебных материалах, потому что Spring Boot ничего не сможет настроить автоматически, когда дело касается расписания. Но если вы совместите этот урок с каким-нибудь другим, то не забудьте добавить её.

Создание приложения исполняемым

Несмотря на то, что запланированные задачи могут быть в составе web-приложения и WAR файлов, более простой подход, продемонстрированный ниже создает отдельное самостоятельное приложение. Вы упаковываете все в единый, исполняемый JAR-файл, который запускается через хорошо знакомый старый main() Java-метод.

На данном этапе вы создаете новый SpringApplication и запускаете его с ScheduledTasks, которые вы определили ранее. Это действие создает задание на выполнение и позволяет задачам запускаться по расписанию.

src/main/java/hello/Application.java

package hello;

import org.springframework.boot.SpringApplication;

public class Application {

    public static void main(String[] args) {
        SpringApplication.run(ScheduledTasks.class, args);
    }
}

Сборка исполняемого JAR

Вы можете собрать единый исполняемый JAR-файл, который содержит все необходимые зависимости, классы и ресурсы. Это делает его легким в загрузке, версионировании и развертывании сервиса как приложения на протяжении всего периода разработки, на различных средах и так далее.

./gradlew build

Затем вы можете запустить JAR-файл:

java -jar build/libs/gs-scheduling-tasks-0.1.0.jar

Если вы используете Maven, вы можете запустить приложение, используя mvn spring-boot:run, либо вы можете собрать приложение с mvn clean package и запустить JAR примерно так:

java -jar target/gs-scheduling-tasks-0.1.0.jar
Процедура, описанная выше, создает исполняемый JAR. Вы также можете вместо него собрать классический WAR-файл.

Запуск сервиса

Если вы используете Gradle, вы можете запустить ваш сервис из командной строки:

./gradlew clean build && java -jar build/libs/gs-scheduling-tasks-0.1.0.jar
Если вы используете Maven, то можете запустить ваш сервис таким образом: mvn clean package && java -jar target/gs-scheduling-tasks-0.1.0.jar.

Как вариант, вы можете запустить ваш сервис напрямую из Gradle примерно так:

./gradlew bootRun
С mvn - mvn spring-boot:run.

Выходные данные отображены. Вы должны увидеть ваши выполненные задачи каждые 5 секунд:

[...]
The time is now 13:10:00
The time is now 13:10:05
The time is now 13:10:10
The time is now 13:10:15

Итог

Поздравляем! Вы только что создали приложение с запланированной задачей. Сверьте, насколько рабочий код короче, чем файл сборки! Эта техника работает в любом типе приложений.

С оригинальным текстом урока вы можете ознакомиться на spring.io.

comments powered by Disqus