Planlægning om foråret med kvarts
1. Oversigt
I denne vejledning bygger vi en simpel Planlægning om foråret med kvarts.
Vi begynder med et simpelt mål for øje - nem konfiguration af et nyt planlagt job.
1.1. Nøglekomponenter i Quartz API
Kvarts har en modulær arkitektur. Den består af flere grundlæggende komponenter, der kan kombineres efter behov. I denne vejledning fokuserer vi på dem, der er fælles for hvert job: Job, Jobdetaljer, Udløser ogPlanlægning.
Selvom vi bruger Spring til at styre applikationen, kan hver enkelt komponent konfigureres på to måder: Kvarts måde eller Forår måde (ved hjælp af dets bekvemmelighedsklasser).
Vi dækker begge dele så vidt muligt for fuldstændighedens skyld, men begge kan vedtages. Lad os begynde at bygge en komponent ad gangen.
2. Job og Jobdetaljer
2.1. Job
API'en giver en Job interface med kun en metode - udføre. Det skal implementeres af den klasse, der indeholder det faktiske arbejde, der skal udføres, dvs. opgaven. Når udløseren af et job udløses, påkalder planlæggeren udføre metode, videregive den a JobExecutionContext objekt.
Det JobExecutionContext giver jobforekomsten oplysninger om dens runtime-miljø, herunder et håndtag til planlæggeren, et håndtag til udløseren og jobets Jobdetaljer objekt.
I dette hurtige eksempel - opgaven delegerer opgaven til en serviceklasse: Mens jobbet er arbejdshesten, gemmer Quartz ikke en faktisk forekomst af jobklassen. I stedet kan vi definere en forekomst af Job bruger Jobdetaljer klasse. Jobets klasse skal leveres til Jobdetaljer så det kender type af det job, der skal udføres. Kvartset JobBuilder giver en builder-stil API til konstruktion Jobdetaljer enheder. Forårets JobDetailFactoryBean giver brug i bønnestil til konfiguration Jobdetaljer tilfælde. Det bruger Spring Bean-navnet som jobnavn, hvis ikke andet er angivet: En ny forekomst af Jobdetaljer oprettes til hver udførelse af jobbet. Det Jobdetaljer objekt formidler de detaljerede egenskaber ved jobbet. Når udførelsen er afsluttet, henvises til forekomsten. EN Udløser er mekanismen til at planlægge en Job, dvs. a Udløser eksempel “fyrer” udførelsen af et job. Der er en klar adskillelse af ansvaret mellem Job (begrebet opgave) og Udløser (planlægningsmekanisme). I tillæg til Job, udløseren har også brug for en type der kan vælges ud fra planlægningskravene. Lad os sige, vi vil planlægge, at vores opgave skal udføres en gang i timen, på ubestemt tid - vi kan bruge kvarts TriggerBuilder eller forårets SimpleTriggerFactoryBean for at gøre det. TriggerBuilder er en builder-stil API til at konstruere Udløser enhed: SimpleTriggerFactoryBean giver brug i bønnestil til konfiguration SimpleTrigger. Det bruger Spring Bean-navnet som udløsernavnet og er standard for ubestemt gentagelse, hvis ikke andet er angivet: JobStore giver lagringsmekanismen til Job og Udløser, og er ansvarlig for at vedligeholde alle de data, der er relevante for jobplanlæggeren. API'en understøtter begge dele i hukommelsen og vedholdende butikker. For eksempel bruger vi in-memory RAMJobStore der tilbyder lynhurtig ydeevne og enkel konfiguration via kvarts. ejendomme: Den åbenlyse ulempe ved RAMJobStore er, at det er flygtige i naturen. Alle planlægningsoplysninger går tabt mellem nedlukninger. Hvis jobdefinitioner og tidsplaner skal holdes mellem nedlukninger, er den vedvarende JDBCJobStore skal bruges i stedet. For at aktivere en hukommelse JobStore om foråret, vi sætter denne ejendom i vores application.properties: Der er to typer JDBCJobStore: JobStoreTX og JobStoreCMT. De gør begge det samme job med at gemme planlægningsoplysninger i en database. Forskellen mellem de to er, hvordan de administrerer de transaktioner, der begår dataene. Det JobStoreCMT type kræver en applikationstransaktion for at gemme data, mens JobStoreTX type starter og administrerer sine egne transaktioner. Der er flere egenskaber, der skal indstilles til en JDBCJobStore. Vi skal som minimum specificere typen af JDBCJobStore, datakilden og databasedriverklassen. Der er førerklasser for de fleste databaser, men StdJDBCDelegate dækker de fleste tilfælde: Opsætning af en JDBC JobStore i foråret tager et par skridt. For det første indstiller vi butiktypen i vores application.properties: Dernæst skal vi aktivere automatisk konfiguration og give Spring den datakilde, der er nødvendig for Quartz-planlæggeren. Det @QuartzDataSource annotation gør det hårde arbejde med at konfigurere og initialisere Quartz-databasen for os: Det Planlægning interface er den vigtigste API til grænseflade med jobplanlæggeren. EN Planlægning kan instantieres med en Planlægningsfabrik. Når de er oprettet, Jobs og Udløsers kan registreres med det. Oprindeligt blev Planlægning er i "stand-by" -tilstand, og dens Start metode skal påberåbes for at starte de tråde, der affyrer udførelsen af job. Ved blot at påberåbe sig getScheduler metode til StdSchedulerFactory, vi kan instantiere Planlægninginitialiser det (med den konfigurerede JobStore og TrådPool), og returner et håndtag til dets API: Forårets SchedulerFactoryBean giver brug i bønnestil til konfiguration af en Planlægning, styrer sin livscyklus inden for applikationens sammenhæng og udsætter Planlægning som en bønne til afhængighedsinjektion: Det SpringBeanJobFactory giver support til at indsprøjte planlægningskonteksten, jobdatakortet og udløse dataposter som egenskaber i jobbønnen, mens du opretter en forekomst. Det mangler dog støtte til injektion af bønnereferencer fra applikationskontekst. Tak til forfatteren af dette blogindlæg kan vi tilføje automatisk ledningsføring støtte til SpringBeanJobFactory ligesom: Det er alt. Vi har netop bygget vores første grundlæggende planlægning ved hjælp af Quartz API såvel som Spring's bekvemmelighedsklasser. Nøgleudtagningen fra denne vejledning er, at vi var i stand til at konfigurere et job med kun et par linjer kode og uden at bruge nogen XML-baseret konfiguration. Det komplette kildekode for eksemplet er tilgængeligt i dette github-projekt. Det er et Maven-projekt, der kan importeres og køre som det er. Standardindstillingen bruger Spring's bekvemmelighedsklasser, som let kan skiftes til Quartz API med en kørselstidsparameter (se README.md i lageret).@Component public class SampleJob implementerer job {@Autowired privat SampleJobService jobService; public void execute (JobExecutionContext context) kaster JobExecutionException {jobService.executeSampleJob (); }}
2.2. Jobdetaljer
2.3. Kvarts JobBuilder
@Bean offentlig JobDetail jobDetail () {return JobBuilder.newJob (). OfType (SampleJob.class) .storeDurably () .withIdentity ("Qrtz_Job_Detail") .withDescription ("Invoke Sample Job service ...") .build (); }
2.4. Forår JobDetailFactoryBean
@Bean public JobDetailFactoryBean jobDetail () {JobDetailFactoryBean jobDetailFactory = ny JobDetailFactoryBean (); jobDetailFactory.setJobClass (SampleJob.class); jobDetailFactory.setDescription ("Invoke Sample Job service ..."); jobDetailFactory.setDurability (true); return jobDetailFactory; }
3. Udløser
3.1. Kvarts TriggerBuilder
@Bean public Trigger trigger (JobDetail job) {return TriggerBuilder.newTrigger (). ForJob (job) .withIdentity ("Qrtz_Trigger") .withDescription ("Sample trigger") .withSchedule (simpleSchedule (). RepeatForever (). WithIntervalInHours (1) )) .build (); }
3.2. Forår SimpleTriggerFactoryBean
@Bean offentlig SimpleTriggerFactoryBean trigger (JobDetail job) {SimpleTriggerFactoryBean trigger = ny SimpleTriggerFactoryBean (); trigger.setJobDetail (job); trigger.setRepeatInterval (3600000); trigger.setRepeatCount (SimpleTrigger.REPEAT_INDEFINITELY); returudløser; }
4. Konfiguration af JobStore
4.1. In-Memory JobStore
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
spring.quartz.job-store-type = hukommelse
4.2. JDBC JobStore
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.jobStore.dataSource = quartzDataSource
spring.quartz.job-store-type = jdbc
@Configuration @EnableAutoConfiguration public class SpringQrtzScheduler {@Bean @QuartzDataSource public DataSource quartzDataSource () {return DataSourceBuilder.create (). Build (); }}
5. Planlægning
5.1. Kvarts StdSchedulerFactory
@Bean public Scheduler scheduler (Trigger trigger, JobDetail job, SchedulerFactoryBean factory) kaster SchedulerException {Scheduler scheduler = factory.getScheduler (); scheduler.scheduleJob (job, trigger); scheduler.start (); returplanlægning; }
5.2. Forår SchedulerFactoryBean
@Bean public SchedulerFactoryBean scheduler (Trigger trigger, JobDetail job, DataSource quartzDataSource) {SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean (); schedulerFactory.setConfigLocation (ny ClassPathResource ("kvarts. ejendomme")); schedulerFactory.setJobFactory (springBeanJobFactory ()); schedulerFactory.setJobDetails (job); schedulerFactory.setTriggers (trigger); schedulerFactory.setDataSource (kvartsDataSource); returplanlæggerFabrik; }
5.3. Konfiguration SpringBeanJobFactory
@Bean public SpringBeanJobFactory springBeanJobFactory () {AutoWiringSpringBeanJobFactory jobFactory = ny AutoWiringSpringBeanJobFactory (); jobFactory.setApplicationContext (applicationContext); retur jobFabrik; }
6. Konklusion