Vårintegrasjon Java DSL

1. Introduksjon

I denne opplæringen lærer vi om Spring Integration Java DSL for å lage applikasjonsintegrasjoner.

Vi tar filflyttingsintegrasjonen vi bygde i Introduksjon til vårintegrasjon og bruker DSL i stedet.

2. Avhengigheter

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

Så vi kan legge til den avhengigheten:

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

Og for å jobbe med filflyttingsprogrammet vårt, trenger vi også Spring Integration File:

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

3. Vårintegrasjon Java DSL

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

DSL introduserer noen flytende byggere som vi enkelt kan lage en komplett vårintegrasjonsrørledning utelukkende i Java.

La oss si at vi ønsket å lage en kanal som verserer alle data som kommer gjennom røret.

Tidligere hadde vi kanskje gjort:

Og nå kan vi i stedet gjøre:

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

4. Filbevegelsesappen

For å starte integrasjonen av filflytting trenger vi noen enkle byggesteiner.

4.1. Integrasjonsflyt

Den første byggesteinen vi trenger er en integrasjonsflyt, som vi kan få fra IntegrationFlows bygger:

IntegrationFlows.from (...)

fra kan ta flere typer, men i denne opplæringen vil vi se på bare tre:

  • MessageSources
  • MessageChannels, og
  • Strings

Vi snakker om alle tre om kort tid.

Etter at vi har ringt fra, noen tilpasningsmetoder er nå tilgjengelige for oss:

IntegrationFlow flow = IntegrationFlows.from (sourceDirectory ()) .filter (onlyJpgs ()) .handle (targetDirectory ()) // legg til flere komponenter .get ();

Til syvende og sist, IntegrationFlows vil alltid produsere en forekomst av IntegrasjonFlow, som er det endelige produktet av en hvilken som helst Spring Integration-app.

Dette mønsteret for å ta innspill, utføre passende transformasjoner og sende ut resultatene er grunnleggende for alle Spring Integration-apper.

4.2. Beskrive en inngangskilde

Først, for å flytte filer, må vi indikere for integrasjonsflyten hvor den skal se etter dem, og for det trenger vi en Meldingskilde:

@Bean public MessageSource sourceDirectory () {// .. opprett en meldingskilde}

Enkelt sagt, a MessageSource er et sted hvor det kan komme meldinger som er eksterne for applikasjonen.

Mer spesifikt trenger vi noe som kan tilpasse den eksterne kilden til vårmeldingsrepresentasjonen. Og siden dette tilpasning er fokusert på inngang, disse kalles ofte Inngangskanaladaptere.

De vår-integrasjonsfil avhengighet gir oss en inngangskanaladapter som er bra for vårt brukstilfelle: FileReadingMessageKilde:

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

Her, vår FileReadingMessageSource vil lese en katalog gitt av INPUT_DIR og vil skape en MessageSource fra det.

La oss spesifisere dette som vår kilde i en IntegrationFlows.from påkallelse:

IntegrationFlows.from (sourceDirectory ());

4.3. Konfigurere en inngangskilde

Nå, hvis vi tenker på dette som en langvarig applikasjon, Vi vil sannsynligvis være i stand til å legge merke til filer når de kommer inn, ikke bare flytte filene som allerede er der ved oppstart.

For å lette dette, fra kan også ta ekstra konfiguratorer som ytterligere tilpasning av inngangskilden:

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

I dette tilfellet kan vi gjøre inngangskilden mer motstandsdyktig ved å fortelle Spring Integration å avstemme den kilden - vårt filsystem i dette tilfellet - hvert 10. sekund.

Og selvfølgelig gjelder dette ikke bare vår filinngangskilde, vi kan legge til denne polleren til hvilken som helst MessageSource.

4.4. Filtrering av meldinger fra en inngangskilde

La oss anta at vi vil at vårt filflyttingsprogram bare skal flytte bestemte filer, sier bildefiler jpg Utvidelse.

For dette kan vi bruke GenericSelector:

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

Så la oss oppdatere integrasjonsflyten vår igjen:

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

Eller, fordi dette filteret er så enkelt, kunne vi i stedet definert det ved hjelp av en lambda:

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

4.5. Håndtering av meldinger med serviceaktivatorer

Nå som vi har en filtrert liste over filer, må vi skrive dem til et nytt sted.

Tjenesteaktivators er det vi henvender oss til når vi tenker på resultater i vårintegrasjon.

La oss bruke FileWritingMessageHandler service aktivator fra vår-integrasjonsfil:

@Bean public MessageHandler targetDirectory () {FileWritingMessageHandler handler = new FileWritingMessageHandler (new File (OUTPUT_DIR)); handler.setFileExistsMode (FileExistsMode.REPLACE); handler.setExpectReply (false); returbehandler; }

Her, vår FileWritingMessageHandler vil skrive hver Beskjed nyttelast den får til OUTPUT_DIR.

Igjen, la oss oppdatere:

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

Og legg merke til forresten bruken av setExpectReply. Fordi integrasjonsflyter kan væretoveis, denne påkallingen indikerer at nettopp dette røret er en vei.

4.6. Aktivering av vår integrasjonsflyt

Når vi har lagt til alle komponentene vi trenger registrer vår IntegrationFlow som en bønne for å aktivere den:

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

Demetoden trekker ut en IntegrationFlow for eksempel at vi må registrere oss som en vårbønne.

Så snart applikasjonskonteksten lastes inn, inneholder alle komponentene våre i vår IntegrationFlow blir aktivert.

Og nå begynner applikasjonen vår å flytte filer fra kildekatalogen til målkatalogen.

5. Ekstra komponenter

I vårt DSL-baserte filflyttingsprogram opprettet vi en inngående kanaladapter, et meldingsfilter og en serviceaktivator.

La oss se på noen andre vanlige Spring Integration-komponenter og se hvordan vi kan bruke dem.

5.1. Meldingskanaler

Som nevnt tidligere, a Meldingskanal er en annen måte å initialisere en flyt på:

IntegrationFlows.from ("anyChannel")

Vi kan lese dette som “finn eller lag en kanalbønne som heter anyChannel. Les deretter data som blir matet inn anyChannel fra andre strømmer. ”

Men egentlig er det mer generelt formål enn det.

Enkelt sagt, en kanal tar bort produsenter fra forbrukere, og vi kan tenke på det som en Java . En kanal kan settes inn når som helst i flyten.

La oss for eksempel si at vi vil prioritere filene når de blir flyttet fra en katalog til en annen:

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

Deretter kan vi sette inn en påkallelse til kanal mellom strømmen vår:

@Bean public IntegrationFlow fileMover () {return IntegrationFlows.from (sourceDirectory ()) .filter (onlyJpgs ()) .channel ("alphabetically") .handle (targetDirectory ()) .get (); }

Det er dusinvis av kanaler å velge mellom, noen av de mer praktiske er for samtidighet, revisjon eller middels utholdenhet (tenk Kafka eller JMS buffere).

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

5.2. Bro

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

La oss forestille oss at i stedet for å skrive direkte til en utdatakatalog, hadde vi i stedet vår filflyttende app til å skrive til en annen kanal:

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

Nå, fordi vi ganske enkelt har skrevet det til en kanal, vi kan bygge bro derfra til andre strømmer.

La oss lage en bro som avstemmer holdetanken vår for meldinger og skriver dem til en destinasjon:

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

Igjen, fordi vi skrev til en mellomkanal, kan vi nå legge til en ny flyt som tar de samme filene og skriver dem med en annen hastighet:

@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 enkelte broer kontrollere valgkonfigurasjonen for forskjellige håndtere.

Så snart applikasjonskonteksten er lastet, har vi nå en mer kompleks app i aksjon som vil begynne å flytte filer fra kildekatalogen til to målkataloger.

6. Konklusjon

I denne artikkelen så vi forskjellige måter å bruke Spring Integration Java DSL til å bygge forskjellige integrasjonsrørledninger.

I hovedsak var vi i stand til å gjenskape filflyttingsprogrammet fra en tidligere veiledning, denne gangen ved hjelp av ren java.

Vi så også på noen andre komponenter som kanaler og broer.

Den komplette kildekoden som brukes i denne opplæringen, er tilgjengelig på Github.


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