Forår Integration Java DSL

1. Introduktion

I denne vejledning lærer vi om Spring Integration Java DSL til oprettelse af applikationsintegrationer.

Vi tager den filflytningsintegration, vi byggede i Introduktion til Spring Integration, og bruger DSL i stedet.

2. Afhængigheder

Spring Integration Java DSL er en del af Spring Integration Core.

Så vi kan tilføje den afhængighed:

 org.springframework.integration spring-integration-core 5.0.6.RELEASE 

Og for at arbejde på vores filoverførselsapplikation har vi også brug for Spring Integration File:

 org.springframework.integration spring-integration-file 5.0.6.RELEASE 

3. Forårsintegration Java DSL

Før Java DSL ville brugerne konfigurere Spring Integration-komponenter i XML.

DSL introducerer nogle flydende bygherrer, hvorfra vi let kan oprette en komplet en Spring Integration-pipeline udelukkende i Java.

Så lad os sige, at vi ønskede at oprette en kanal, der verserer alle data, der kommer gennem røret.

Tidligere har vi muligvis gjort:

Og nu kan vi i stedet gøre:

@Bean public IntegrationFlow upcaseFlow () {return IntegrationFlows.from ("input") .transform (String :: toUpperCase) .get (); }

4. Fil-flytning-appen

For at begynde vores filoverførselsintegration har vi brug for nogle enkle byggesten.

4.1. Integrationsflow

Den første byggesten, vi har brug for, er en integrationsstrøm, som vi kan få fra IntegrationFlows Bygger:

IntegrationFlows.from (...)

fra kan tage flere typer, men i denne vejledning ser vi på kun tre:

  • MessageSources
  • MessageChannels, og
  • Snors

Vi taler om alle tre inden længe.

Efter vi har ringet fra, nogle tilpasningsmetoder er nu tilgængelige for os:

IntegrationFlow flow = IntegrationFlows.from (sourceDirectory ()) .filter (onlyJpgs ()) .handle (targetDirectory ()) // tilføj flere komponenter .get ();

Ultimativt, IntegrationFlows vil altid producere en forekomst af IntegrationFlow, som er det endelige produkt af enhver Spring Integration-app.

Dette mønster for at tage input, udføre de relevante transformationer og udsende resultaterne er grundlæggende for alle Spring Integration-apps.

4.2. Beskrivelse af en inputkilde

For det første skal vi for at flytte filer angive for vores integrationsflow, hvor det skal se efter dem, og til det har vi brug for en Beskedkilde:

@Bean public MessageSource sourceDirectory () {// .. opret en meddelelseskilde}

Kort sagt, en MessageSource er et sted, hvorfra der kan komme beskeder, der er eksterne for applikationen.

Mere specifikt har vi brug for noget, der kan tilpasse den eksterne kilde i Spring messaging-repræsentationen. Og siden dette tilpasning er fokuseret på input, disse kaldes ofte Indgangskanaladaptere.

Det fjeder-integrationsfil afhængighed giver os en inputkanaladapter, der er fantastisk til vores brugssag: FileReadingMessageKilde:

@Bean offentlig MessageSource sourceDirectory () {FileReadingMessageSource messageSource = ny FileReadingMessageSource (); messageSource.setDirectory (ny fil (INPUT_DIR)); returnere beskedKilde; }

Her, vores FileReadingMessageSource læser en mappe givet af INPUT_DIR og vil skabe en MessageSource fra det.

Lad os specificere dette som vores kilde i en IntegrationFlows.from påkaldelse:

IntegrationFlows.from (sourceDirectory ());

4.3. Konfiguration af en inputkilde

Hvis vi nu tænker på dette som en langvarig applikation, Vi vil sandsynligvis være i stand til at bemærke filer, når de kommer ind, ikke bare flytte de filer, der allerede er der ved opstart.

For at lette dette, fra kan også tage ekstra konfiguratorer som yderligere tilpasning af inputkilden:

IntegrationFlows.from (sourceDirectory (), configurer -> configurer.poller (Pollers.fixedDelay (10000)));

I dette tilfælde kan vi gøre vores inputkilde mere modstandsdygtig ved at fortælle Spring Integration at afstemme den kilde - vores filsystem i dette tilfælde - hvert 10. sekund.

Og selvfølgelig gælder dette ikke kun vores filinputkilde, vi kunne tilføje denne poller til enhver MessageSource.

4.4. Filtrering af meddelelser fra en inputkilde

Lad os antage, at vi kun vil have, at vores filoverførselsapplikation skal flytte specifikke filer, siger billedfiler, der har jpg udvidelse.

Til dette kan vi bruge GenericSelector:

@Bean public GenericSelector onlyJpgs () {return new GenericSelector () {@Override public boolean accept (File source) {return source.getName (). EndsWith (". Jpg"); }}; }

Så lad os opdatere vores integrationsflow igen:

IntegrationFlows.from (sourceDirectory ()) .filter (onlyJpgs ());

Eller, fordi dette filter er så simpelt, kunne vi i stedet have defineret det ved hjælp af en lambda:

IntegrationFlows.from (sourceDirectory ()) .filter (source -> ((File) source) .getName (). EndsWith (". Jpg"));

4.5. Håndtering af meddelelser med serviceaktivatorer

Nu hvor vi har en filtreret liste over filer, skal vi skrive dem til en ny placering.

Serviceaktivators er, hvad vi henvender os til, når vi tænker på output i Spring Integration.

Lad os bruge FileWritingMessageHandler service aktivator fra fjeder-integrationsfil:

@Bean public MessageHandler targetDirectory () {FileWritingMessageHandler handler = ny FileWritingMessageHandler (ny fil (OUTPUT_DIR)); handler.setFileExistsMode (FileExistsMode.REPLACE); handler.setExpectReply (false); returhandler }

Her, vores FileWritingMessageHandler vil skrive hver Besked nyttelast, den modtager til OUTPUT_DIR.

Lad os igen opdatere:

IntegrationFlows.from (sourceDirectory ()) .filter (onlyJpgs ()) .handle (targetDirectory ());

Og bemærk forresten brugen af setExpectReply. Fordi integrationsstrømme kan væretovejs, denne påkaldelse indikerer, at netop dette rør er en vej.

4.6. Aktivering af vores integrationsflow

Når vi har tilføjet alle vores komponenter, har vi brug for det registrer vores IntegrationFlow som en bønne for at aktivere det:

@Bean public IntegrationFlow fileMover () {return IntegrationFlows.from (sourceDirectory (), c -> c.poller (Pollers.fixedDelay (10000))) .filter (onlyJpgs ()) .handle (targetDirectory ()) .get () ; }

Detmetode ekstrakter en IntegrationFlow eksempel, at vi skal registrere os som en Spring Bean.

Så snart vores applikationskontekst indlæses, er alle vores komponenter indeholdt i vores IntegrationFlow bliver aktiveret.

Og nu begynder vores applikation at flytte filer fra kildekataloget til målkataloget.

5. Yderligere komponenter

I vores DSL-baserede filoverførselsapplikation oprettede vi en indgående kanaladapter, et meddelelsesfilter og en serviceaktiver.

Lad os se på et par andre almindelige Spring Integration-komponenter og se, hvordan vi kan bruge dem.

5.1. Beskedkanaler

Som nævnt tidligere, a Meddelelseskanal er en anden måde at initialisere et flow på:

IntegrationFlows.from ("anyChannel")

Vi kan læse dette som “find eller opret en kanalbønne kaldet anyChannel. Læs derefter alle data, der indføres anyChannel fra andre strømme. ”

Men det er virkelig mere generelt formål end det.

Kort sagt, en kanal abstraherer producenter fra forbrugere, og vi kan tænke på det som en Java . En kanal kan indsættes når som helst i strømmen.

Lad os f.eks. Sige, at vi vil prioritere filerne, når de flyttes fra en mappe til den næste:

@Bean offentlig PriorityChannel alfabetisk () {returner ny PriorityChannel (1000, (venstre, højre) -> ((File) left.getPayload ()). GetName (). CompareTo (((File) right.getPayload ()). GetName ())); }

Derefter kan vi indsætte en påkaldelse til kanal imellem vores flow:

@Bean public IntegrationFlow fileMover () {return IntegrationFlows.from (sourceDirectory ()) .filter (onlyJpgs ()) .channel ("alfabetisk"). Håndtag (targetDirectory ()) .get (); }

Der er snesevis af kanaler at vælge imellem, nogle af de mere praktiske er for samtidighed, revision eller mellemliggende vedholdenhed (tænk Kafka- eller JMS-buffere).

Kanaler kan også være effektive, når de kombineres med Bros.

5.2. Bro

Når vi vil kombinere to kanaler, vi bruger en Bro.

Lad os forestille os, at i stedet for at skrive direkte til en outputkatalog, havde vi i stedet vores filoverførelsesapp til en anden kanal:

@Bean public IntegrationFlow fileReader () {return IntegrationFlows.from (sourceDirectory ()) .filter (onlyJpgs ()) .channel ("holdingTank") .get (); }

Nu, fordi vi simpelthen har skrevet det til en kanal, vi kan bygge bro derfra til andre strømme.

Lad os oprette en bro, der afstemmer vores holdetank for beskeder og skriver dem til en destination:

@Bean public IntegrationFlow fileWriter () {return IntegrationFlows.from ("holdingTank") .bridge (e -> e.poller (Pollers.fixedRate (1, TimeUnit.SECONDS, 20))) .handle (targetDirectory ()) .get (); }

Igen, fordi vi skrev til en mellemkanal, kan vi nu tilføje endnu en strøm der tager de samme filer og skriver dem med en anden hastighed:

@Bean public IntegrationFlow anotherFileWriter () {return IntegrationFlows.from ("holdingTank") .bridge (e -> e.poller (Pollers.fixedRate (2, TimeUnit.SECONDS, 10))) .handle (anotherTargetDirectory ()) .get (); }

Som vi kan se, kan individuelle broer styre afstemningskonfigurationen for forskellige behandlere.

Så snart vores applikationskontekst er indlæst, har vi nu en mere kompleks app i aktion, der begynder at flytte filer fra kildemappen til to målmapper.

6. Konklusion

I denne artikel så vi forskellige måder at bruge Spring Integration Java DSL til at opbygge forskellige integrationsrørledninger.

I det væsentlige var vi i stand til at genskabe filoverførselsapplikationen fra en tidligere tutorial, denne gang ved hjælp af ren java.

Vi kiggede også på et par andre komponenter som kanaler og broer.

Den komplette kildekode, der bruges i denne vejledning, er tilgængelig på Github.


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