Planlægning i Jakarta EE

1. Oversigt

I en tidligere artikel demonstrerede vi, hvordan man planlægger opgaver i foråret@ Planlagtkommentar. I denne artikel vil vi demonstrere, hvordan man opnår det samme ved hjælp af timertjenesten i et Jakarta EE-program for hvert tilfælde præsenteret i den foregående artikel.

2. Aktivér support til planlægning

I en Jakarta EE-applikation er der ikke behov for at aktivere support til tidsbestemte opgaver. Timertjenesten er en containeradministreret tjeneste, der giver applikationer mulighed for at kalde metoder, der er planlagt til tidsbaserede begivenheder. Som et eksempel kan en applikation muligvis køre nogle daglige rapporter på et bestemt tidspunkt for at generere statistik.

Der er to typer timere:

  • Programmatiske timere: timertjenesten kan injiceres i enhver bønne (undtagen en stateful session bønne), og forretningslogikken skal placeres i en metode, der er kommenteret med @Tiden er gået. Timeren kan initialiseres efter en metode, der er kommenteret @PostConstruct af bønnerne, eller det kan også initialiseres bare ved at kalde en metode.
  • Automatiske timere: Forretningslogikken placeres i enhver metode, der er kommenteret med @Tidsplan eller @Planer. Disse timere initialiseres, så snart applikationen starter.

Så lad os komme i gang med vores første eksempel.

3. Planlæg opgave med en fast forsinkelse

I foråret gøres dette blot ved at bruge @ Planlagt (fixedDelay = 1000) kommentar. I dette tilfælde er varigheden mellem slutningen af ​​den sidste udførelse og starten af ​​den næste udførelse fast. Opgaven venter altid, indtil den forrige er færdig.

At gøre nøjagtigt det samme i Jakarta EE er lidt sværere at opnå, fordi der ikke findes nogen lignende indbygget mekanisme, alligevel kan et lignende scenario implementeres med lidt ekstra kodning. Lad os se på, hvordan dette gøres:

@Singleton offentlig klasse FixedTimerBean {@EJB privat WorkerBean workerBean; @Lock (LockType.READ) @Schedule (second = "* / 5", minute = "*", hour = "*", persistent = false) offentligt ugyldigt atSchedule () kaster InterruptedException {workerBean.doTimerWork (); }} 
@Singleton offentlig klasse WorkerBean {privat AtomicBoolean optaget = ny AtomicBoolean (falsk); @Lock (LockType.READ) offentlig ugyldighed doTimerWork () kaster InterruptedException {if (! Busy.compareAndSet (false, true)) {return; } prøv {Thread.sleep (20000L); } endelig {busy.set (false); }}}

Som du kan se, er timeren planlagt til at blive udløst hvert femte sekund. Men den metode, der blev udløst i vores tilfælde, simulerede en 20 sekunders svartid ved opkald søvn() på strømmen Tråd.

Som en konsekvens fortsætter containeren med at ringe doTimerWork () hvert femte sekund, men tilstanden i starten af ​​metoden, busy.compareAndSet (false, true), vender straks tilbage, hvis det forrige opkald ikke er afsluttet. I dette sikrer vi, at den næste opgave først udføres, når den foregående er afsluttet.

4. Planlæg opgave til en fast sats

En måde at gøre dette på er at bruge den timertjeneste, der injiceres ved hjælp af @Ressource og konfigureret i den kommenterede metode @PostConstruct. Metoden kommenteret med @Tiden er gået kaldes, når timeren udløber.

Som nævnt i den foregående artikel venter starten af ​​opgaveudførelsen ikke på afslutningen af ​​den tidligere udførelse. Denne mulighed skal bruges, når hver udførelse af opgaven er uafhængig. Følgende kodestykke opretter en timer, der udløses hvert sekund:

@Startup @ Singleton offentlig klasse ProgrammaticAtFixedRateTimerBean {@Inject Event event; @Resource TimerService timerService; @PostConstruct public void initialize () {timerService.createTimer (0,1000, "Hver anden timer uden forsinkelse"); } @Timeout offentlig ugyldig programmaticTimout (Timer timer) {event.fire (new TimerEvent (timer.getInfo (). ToString ())); }}

En anden måde er at bruge @ Planlagt kommentar. I det følgende kodestykke affyrer vi en timer hvert femte sekund:

@Startup @ Singleton offentlig klasse ScheduleTimerBean {@Inject Event event; @Schedule (hour = "*", minute = "*", second = "* / 5", info = "Every 5 seconds timer") offentlig ugyldig automatisk Planlagt (Timer timer) {fireEvent (timer); } privat ugyldigt fireEvent (Timer timer) {event.fire (new TimerEvent (timer.getInfo (). toString ())); }}

5. Planlæg opgave med indledende forsinkelse

Hvis dit use case-scenario kræver, at timeren starter med en forsinkelse, kan vi også gøre det. I dette tilfælde tillader Jakarta EE brugen af ​​timertjenesten. Lad os se på et eksempel, hvor timeren har en indledende forsinkelse på 10 sekunder og derefter affyrer hvert femte sekund:

@Startup @Singleton offentlig klasse ProgrammaticWithInitialFixedDelayTimerBean {@Inject Event event; @Resource TimerService timerService; @PostConstruct public void initialize () {timerService.createTimer (10000, 5000, "Delay 10 seconds then every 5 seconds timer"); } @Timeout offentlig ugyldig programmaticTimout (Timer timer) {event.fire (new TimerEvent (timer.getInfo (). ToString ())); }}

Det createTimer metoden anvendt i vores prøve bruger følgende signatur createTimer (lang initialDuration, langt intervalDuration, java.io.Serialiserbar info) hvor initialDuration er antallet af millisekunder, der skal gå, før meddelelsen om første udløb af timeren og intervalVarighed er det antal millisekunder, der skal gå mellem meddelelser om udløb af timer.

I dette eksempel bruger vi en initialDuration på 10 sekunder og en intervalVarighed på fem sekunder. Opgaven udføres første gang efter initialDuration værdi, og den vil fortsat blive udført i henhold til intervalVarighed.

6. Planlæg opgave ved hjælp af Cron Expressions

Alle de planlæggere, vi har set, både programmatiske og automatiske, tillader brug af cron-udtryk. Lad os se et eksempel:

@Schedules ({@Schedule (dayOfMonth = "Sidste"), @Schedule (dayOfWeek = "fre", time = "23")}) offentlig ugyldig doPeriodicCleanup () {...}

I dette eksempel er metoden doPeriodicCleanup () kaldes op hver fredag ​​kl. 23:00 og den sidste dag i måneden.

7. Konklusion

I denne artikel har vi set på forskellige måder at planlæg opgaver i Jakarta EE-miljøet ved hjælp af en tidligere artikel, hvor prøver blev udført ved hjælp af Spring, som udgangspunkt.

Kodeprøver kan findes i GitHub-arkivet.


$config[zx-auto] not found$config[zx-overlay] not found