Heim >Java >javaLernprogramm >So implementieren Sie mehrere geplante Aufgaben in Spring Boot

So implementieren Sie mehrere geplante Aufgaben in Spring Boot

Java后端技术全栈
Java后端技术全栈nach vorne
2023-08-15 16:50:341461Durchsuche

In der tatsächlichen Entwicklung werden wir mehr oder weniger einige geplante Aufgabenszenarien verwenden. In diesem Artikel geht es um häufig verwendete geplante Aufgaben.

Zu den häufig verwendeten Lösungen zur Implementierung geplanter Aufgaben gehören die folgenden:

  • java.util.TimerTaskAufgabe. Mit dieser Methode kann Ihr Programm mit einer bestimmten Häufigkeit, jedoch nicht zu einem bestimmten Zeitpunkt ausgeführt werden. Im Allgemeinen weniger verwendet. Timer:这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行。一般用的较少。
  • ScheduledExecutorService:也jdk自带的一个类;是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响。
  • Spring TaskSpring3.0以后自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多。
  • Quartz
  • Die Aufgaben, die mit Spring 3.0 geliefert werden können wie folgt aussehen wie ein leichter Quarz und ist viel einfacher zu verwenden als Quarz.
    Erstellen Sie in der Datenbank eine Tabelle und speichern Sie Cron-Ausdrücke in der Tabelle.
  • nacos verwendet verteilte Konfiguration, um dynamische Konfigurations-Cron-Ausdrücke zu implementieren.

    XXL-JOB, verteilte feste Aufgabe

    🎜🎜Timer verwenden🎜🎜 🎜🎜🎜Dieser wird derzeit weniger im Projekt verwendet und der Democode wird direkt gepostet. 🎜🎜Eine ausführliche Einführung finden Sie in der API: 🎜
    public class TestTimer {
        public static void main(String[] args) {
            TimerTask timerTask = new TimerTask() {
                @Override
                public void run() {
                    System.out.println("task  run:"+ new Date());
                }
            };
            Timer timer = new Timer();
            //安排指定的任务在指定的时间开始进行重复的固定延迟执行。这里是每3秒执行一次
            timer.schedule(timerTask,10,3000);
        }
    }

    Verwenden Sie ScheduledExecutorService

    Diese Methode ähnelt Timer, schauen Sie sich einfach die Demo an:

    public class TestScheduledExecutorService {
        public static void main(String[] args) {
            ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
            // 参数:1、任务体 2、首次执行的延时时间
            //      3、任务执行间隔 4、间隔时间单位
            service.scheduleAtFixedRate(()->System.out.println("task ScheduledExecutorService "+new Date()), 0, 3, TimeUnit.SECONDS);
        }
    }

    Verwenden Sie Spring Task

    Einfache geplante Aufgabe

    Im Spring Boot-Projekt können wir Benutze es Sehr elegante Annotation zum Implementieren geplanter Aufgaben. Erstellen Sie zunächst ein Projekt und importieren Sie Abhängigkeiten:

    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
      </dependency>
      <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
      </dependency>
    </dependencies>

    Erstellen Sie eine Aufgabenklasse:

    @Slf4j
    @Component
    public class ScheduledService {
        @Scheduled(cron = "0/5 * * * * *")
        public void scheduled(){
            log.info("=====>>>>>使用cron  {}",System.currentTimeMillis());
        }
        @Scheduled(fixedRate = 5000)
        public void scheduled1() {
            log.info("=====>>>>>使用fixedRate{}", System.currentTimeMillis());
        }
        @Scheduled(fixedDelay = 5000)
        public void scheduled2() {
            log.info("=====>>>>>fixedDelay{}",System.currentTimeMillis());
        }
    }

    Verwenden Sie die Annotation @EnableScheduling für die Hauptklasse, um die Unterstützung für geplante Aufgaben zu aktivieren, und starten Sie dann das Projekt

    So implementieren Sie mehrere geplante Aufgaben in Spring Boot

    Sie können sehen, dass alle geplanten Aufgaben nacheinander im selben Thread ausgeführt wurden. Wenn die Anzahl der geplanten Aufgaben zunimmt, ist dies definitiv kein Problem Wenn der Fehler stecken bleibt, können andere Aufgaben nicht ausgeführt werden.

    Multithread-Ausführung

    In herkömmlichen Spring-Projekten können wir die Aufgabenkonfiguration in der XML-Konfigurationsdatei hinzufügen. In Spring Boot-Projekten verwenden wir im Allgemeinen die Konfigurationsklasse config, um die Konfiguration hinzuzufügen. Erstellen Sie daher eine neue AsyncConfig Klasse AsyncConfig

    @Configuration
    @EnableAsync
    public class AsyncConfig {
         /*
        此处成员变量应该使用@Value从配置中读取
         */
        private int corePoolSize = 10;
        private int maxPoolSize = 200;
        private int queueCapacity = 10;
        @Bean
        public Executor taskExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(corePoolSize);
            executor.setMaxPoolSize(maxPoolSize);
            executor.setQueueCapacity(queueCapacity);
            executor.initialize();
            return executor;
        }
    }

    @Configuration:表明该类是一个配置类@EnableAsync:开启异步事件的支持

    然后在定时任务的类或者方法上添加@Async

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-quartz</artifactId>
    </dependency>

    @Configuration: Gibt an, dass die Klasse eine Konfigurationsklasse ist@EnableAsync: Unterstützung für asynchrone Ereignisse aktivieren

    So implementieren Sie mehrere geplante Aufgaben in Spring BootDann in der Klasse oder Methode der geplanten Aufgabe hinzufügen @Async . Starten Sie abschließend das Projekt neu. Jede Aufgabe befindet sich in einem anderen Thread.

    Konfiguration der Ausführungszeit🎜🎜In der oben genannten geplanten Aufgabe verwenden wir die Annotation @Scheduled für die Methode, um die Ausführungszeit der Aufgabe festzulegen, und verwenden drei Attributkonfigurationsmethoden: 🎜
    1. fixedRate: Definieren Sie eine geplante Aufgabe, die in einer bestimmten Häufigkeit ausgeführt wird.
    2. fixedDelay: Definieren Sie eine geplante Aufgabe, die in einer bestimmten Häufigkeit ausgeführt wird. Der Unterschied zu den oben genannten besteht darin, dass das Ändern des Attributs mit initialDelay zusammenwirken kann Definieren Sie die verzögerte Ausführungszeit der Aufgabe.
    3. cron: Aufgabenausführungszeit über Ausdrücke konfigurieren

    Detaillierte Erklärung von Cron-Ausdrücken

    Ein Cron-Ausdruck besteht aus mindestens 6 (vielleicht 7) Zeitelementen, die durch Leerzeichen getrennt sind. In der Reihenfolge:

    • Sekunden (0~59)
    • Minuten (0~59)
    • 3 Stunden (0~23)
    • 4 Tage (0~31)
    • 5 Monate (0~11)
    • 6 Wochen (1~7 1=SONNE oder SO, MO, DIE, MITTWOCH, DO, FREI, SA)
    • Jahr (1970-2099)

    Jedes Element kann ein Wert (z. B. 6), ein kontinuierliches Intervall (9-12), ein Intervall (8-18/4) (/ bedeutet alle 4 Stunden), eine Liste (1, 3, 5) oder ein Platzhalter sein. Da sich die beiden Elemente „Tag des Monats“ und „Tag der Woche“ gegenseitig ausschließen, muss eines davon festgelegt werden. Konfigurationsbeispiel:

    • Alle 5 Sekunden ausgeführt: */5* * ?
    • Alle 1 Minute ausgeführt: 0 /1 ?
    • 0 0 10,14,16 ? Jeden Tag um 10 Uhr, 14 Uhr, 16 Uhr
    • 0 0/30 9-17 ? Jede halbe Stunde während 9 bis 5 Arbeitsstunden
    • 0 0 12 ? *MI bedeutet jeden Mittwoch um 12 Uhr
    • " 0 0 12 ?" um 12 Uhr
    • "0 15 10 ? "Jeden Tag um 10:15 Uhr auslösen
    • "0 15 10 ?" Jeden Tag um 10:15 Uhr auslösen
    • "0 15 10 ? *" Wird jeden Tag um 10:15 Uhr ausgelöst Wird alle 1 Minute während 59 ausgelöst
    • "0 0/5 14 ?" Wird jeden Tag von 14:00 bis 14:55 Uhr alle 5 Minuten ausgelöst
    • "0 0/5 14,18 ?" bis 14:55 Uhr und alle 5 Minuten von 18:00 bis 18:55 Uhr
    • "0 0-5 14 ?" Wird jeden Tag von 14:00 bis 14:05 Uhr alle 1 Minute ausgelöst Auslöser
    • "0 10,44 14 ? 3 MI“ jeden Mittwoch im März um 14:10 und 14:44 Uhr Auslöser
    • “0 15 10 ? * MO-FR“ Montag bis Freitagmorgen Auslöser um 10:15
    • “0 15 10 15 * ?" Wird am 15. eines jeden Monats um 10:15 Uhr ausgelöst am letzten Freitag jedes Monats um 10:15 Uhr
    • "0 15 10 ? * 6L 2002-2005" Wird am letzten Freitag jedes Monats um 10:15 Uhr von 2002 bis 2005 ausgelöst: 15 Auslöser
    • " 0 15 10 ? * 6#3" Wird jeden dritten Freitag im Monat um 10:15 Uhr ausgelöst
    • Einige Unterausdrücke können einige Bereiche oder Listen enthalten
    • Zum Beispiel: Unterausdruck Die Formel (Tag (Woche)) kann sei „MON-FR“, „MON, WED, FRI“, „MON-WED, SAT“
    • Das Zeichen „*“ steht für alle möglichen Werte Das Zeichen „/“ wird verwendet, um die Erhöhung des Werts anzugeben

      Zum Beispiel: „0/15“ im Unterausdruck (Minuten) bedeutet, dass alle 15 Minuten bei Minute 0 begonnen wird „3/20“ im Unterausdruck (Minuten) bedeutet, dass ab der 3. Minute alle 20 Minuten (es hat die gleiche Bedeutung wie „3, 23, 43“)

      Das „?“-Zeichen wird nur für Tage verwendet Zwei Unterausdrücke (Monat) und Tag (Woche), die angeben, dass kein Wert angegeben ist Wenn einem der beiden Unterausdrücke ein Wert zugewiesen wird, muss der Wert des anderen Unterausdrucks auf „?“ gesetzt werden, um Konflikte zu vermeiden. Das Zeichen „L“ wird nur für Tag (Monat) und Tag (Woche) verwendet ) ) zwei Unterausdrücke, die für das Wort „last“ kurz sind Wenn vor dem „L“ etwas Bestimmtes steht, hat es eine andere Bedeutung.

      Zum Beispiel: „6L“ bedeutet den 6. vorletzten Tag dieses Monats Hinweis: Geben Sie bei Verwendung des Parameters „L“ keine Liste oder keinen Bereich an, da dies zu Problemen führt.

      Das W-Zeichen steht für Wochentage (Mo-Fr) und kann nur im Tagesbereich verwendet werden. Es wird verwendet, um den Wochentag anzugeben, der dem angegebenen Tag am nächsten liegt. Die meisten Geschäftsabwicklungen basieren auf der Arbeitswoche, daher kann das W-Zeichen sehr wichtig sein.

      Zum Beispiel bedeutet 15W im Tagesfeld „der Wochentag, der dem 15. des Monats am nächsten liegt“. Wenn der 15. ein Samstag ist, wird der Auslöser am 14. (Freitag) ausgelöst, da der Donnerstag näher am Tag liegt 15. als Montag geschlossen.

      C: steht für „Kalender“. Dies bedeutet das mit dem Zeitplan verknüpfte Datum oder alle Daten im Kalender, wenn das Datum nicht verknüpft ist.

      Zum Beispiel entspricht 5C im Datumsfeld dem ersten Tag nach dem 5. im Kalender. 1C im Feld „Wochentag“ entspricht dem ersten Tag nach Sonntag.
      Feld zulässige Werte zulässige Sonderzeichen
      Sekunden 0~59 , - * /
      Minuten 0 ~59 , - * + ?? /

      在线cron表达式生成:http://qqe2.com/cron/index

      整合Quartz

      • 添加依赖

      如果Spring Boot版本是2.0.0以后的,则在spring-boot-starter中已经包含了quart的依赖,则可以直接使用spring-boot-starter-quartz依赖:

      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-quartz</artifactId>
      </dependency>

      如果是1.5.9则要使用以下添加依赖:

      <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.3.0</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
      </dependency>

      这里我使用Spring Boot版本是2.0.0.BUILD-SNAPSHOT ,该版本开始集成了Quartz,所以事实现起来很方便。其它好像比较麻烦,这里就不介绍,以后有时间再详细深入了解Quartz。

      • 创建任务类TestQuartz,该类主要是继承了QuartzJobBean
      public class TestQuartz extends QuartzJobBean {
          /**
           * 执行定时任务
           * @param jobExecutionContext
           * @throws JobExecutionException
           */
          @Override
          protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
              System.out.println("quartz task "+new Date());
          }
      }
      • 创建配置类QuartzConfig
      @Configuration
      public class QuartzConfig {
          @Bean
          public JobDetail teatQuartzDetail(){
              return JobBuilder.newJob(TestQuartz.class).withIdentity("testQuartz").storeDurably().build();
          }
      
          @Bean
          public Trigger testQuartzTrigger(){
              SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                      .withIntervalInSeconds(10)  //设置时间周期单位秒
                      .repeatForever();
              return TriggerBuilder.newTrigger().forJob(teatQuartzDetail())
                      .withIdentity("testQuartz")
                      .withSchedule(scheduleBuilder)
                      .build();
          }
      }
      • 启动项目

      So implementieren Sie mehrere geplante Aufgaben in Spring Boot

      最后

      上面都是简单的介绍了关于Spring Boot定时任务的处理,直接使用SpringTask注解的方式应该是最方便的,而使用Quartz从2.0开始也变得很方便。对于这两种方式,应该说各有长处吧,按需选择。

    Das obige ist der detaillierte Inhalt vonSo implementieren Sie mehrere geplante Aufgaben in Spring Boot. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Stellungnahme:
    Dieser Artikel ist reproduziert unter:Java后端技术全栈. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen