Spring-integratie Java DSL

1. Inleiding

In deze zelfstudie leren we over de Spring Integration Java DSL voor het maken van applicatie-integraties.

We nemen de bestandsverplaatsende integratie die we hebben gebouwd in Inleiding tot Spring Integration en gebruiken in plaats daarvan de DSL.

2. Afhankelijkheden

De Spring Integration Java DSL is onderdeel van Spring Integration Core.

Dus we kunnen die afhankelijkheid toevoegen:

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

En om aan onze applicatie voor het verplaatsen van bestanden te werken, hebben we ook Spring Integration File nodig:

 org.springframework.integration spring-integratie-bestand 5.0.6.RELEASE 

3. Lente-integratie Java DSL

Vóór de Java DSL zouden gebruikers Spring Integration-componenten in XML configureren.

De DSL introduceert enkele vloeiende builders van waaruit we eenvoudig een complete Spring Integration-pijplijn kunnen maken, puur in Java.

Dus, laten we zeggen dat we een kanaal wilden maken dat alle gegevens die door de pipe binnenkomen, in hoofdletters zet.

In het verleden hebben we misschien gedaan:

En nu kunnen we in plaats daarvan doen:

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

4. De app voor het verplaatsen van bestanden

Om onze integratie van het verplaatsen van bestanden te starten, hebben we enkele eenvoudige bouwstenen nodig.

4.1. Integratiestroom

De eerste bouwsteen die we nodig hebben, is een integratiestroom, die we kunnen halen uit het IntegrationFlows bouwer:

IntegrationFlows.from (...)

van kan verschillende typen aannemen, maar in deze tutorial zullen we er slechts drie bekijken:

  • MessageSources
  • MessageChannels, en
  • Draads

We zullen het binnenkort over alle drie hebben.

Nadat we hebben gebeld vanzijn er nu enkele aanpassingsmethoden voor ons beschikbaar:

IntegrationFlow flow = IntegrationFlows.from (sourceDirectory ()) .filter (onlyJpgs ()) .handle (targetDirectory ()) // voeg meer componenten toe .get ();

Uiteindelijk, IntegrationFlows zal altijd een exemplaar produceren van IntegrationFlow, dat is het eindproduct van elke Spring Integration-app.

Dit patroon van het nemen van input, het uitvoeren van de juiste transformaties en het uitzenden van de resultaten is fundamenteel voor alle Spring Integration-apps.

4.2. Een invoerbron beschrijven

Om bestanden te verplaatsen, moeten we eerst aan onze integratiestroom aangeven waar deze ernaar moet zoeken, en daarvoor hebben we een Bericht Bron:

@Bean openbare MessageSource sourceDirectory () {// .. maak een berichtbron}

Simpel gezegd, een MessageSource is een plek waar berichten vandaan kunnen komen die buiten de applicatie liggen.

Meer specifiek hebben we iets nodig dat kan zich aanpassen die externe bron in de Spring Messaging-weergave. En sinds dit aanpassing is gericht op invoer, worden deze vaak genoemd Ingangskanaaladapters.

De spring-integratie-bestand afhankelijkheid geeft ons een invoerkanaaladapter die geweldig is voor ons gebruik: FileReadingMessageSource:

@Bean openbare MessageSource sourceDirectory () {FileReadingMessageSource messageSource = nieuwe FileReadingMessageSource (); messageSource.setDirectory (nieuw bestand (INPUT_DIR)); terug messageSource; }

Hier, onze FileReadingMessageSource zal een map lezen die is gegeven door INPUT_DIR en zal een MessageSource van het.

Laten we dit specificeren als onze bron in een IntegrationFlows.from aanroeping:

IntegrationFlows.from (sourceDirectory ());

4.3. Een invoerbron configureren

Als we dit nu beschouwen als een langdurige applicatie, we willen waarschijnlijk bestanden kunnen opmerken zodra ze binnenkomen, verplaats niet alleen de bestanden die al aanwezig zijn bij het opstarten.

Om dit te vergemakkelijken, van kan ook extra nemen configuratoren als verdere aanpassing van de invoerbron:

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

In dit geval kunnen we onze invoerbron veerkrachtiger maken door Spring Integration te vertellen om die bron - in dit geval ons bestandssysteem - elke 10 seconden te pollen.

En dit is natuurlijk niet alleen van toepassing op onze bestandsinvoerbron, we zouden deze poller aan elke bron kunnen toevoegen MessageSource.

4.4. Berichten filteren van een invoerbron

Laten we vervolgens aannemen dat we willen dat onze applicatie voor het verplaatsen van bestanden alleen specifieke bestanden verplaatst, bijvoorbeeld afbeeldingsbestanden met jpg uitbreiding.

Hiervoor kunnen we gebruik maken van GenericSelector:

@Bean public GenericSelector onlyJpgs () {retourneer nieuwe GenericSelector () {@Override public boolean accept (Bestandsbron) {retourneer source.getName (). EndsWith (". Jpg"); }}; }

Dus laten we onze integratiestroom opnieuw updaten:

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

Of, omdat dit filter zo eenvoudig is, hadden we het in plaats daarvan kunnen definiëren met een lambda:

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

4.5. Berichten afhandelen met serviceactivatoren

Nu we een gefilterde lijst met bestanden hebben, moeten we ze naar een nieuwe locatie schrijven.

Dienst Activators zijn waar we naar kijken als we nadenken over output in Spring Integration.

Laten we de FileWritingMessageHandler service activator van spring-integratie-bestand:

@Bean openbare MessageHandler targetDirectory () {FileWritingMessageHandler-handler = nieuwe FileWritingMessageHandler (nieuw bestand (OUTPUT_DIR)); handler.setFileExistsMode (FileExistsMode.REPLACE); handler.setExpectReply (false); terugkeer afhandelaar; }

Hier, onze FileWritingMessageHandler zal elk schrijven Bericht payload die het ontvangt OUTPUT_DIR.

Nogmaals, laten we updaten:

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

En let trouwens op het gebruik van setExpectReply. Omdat integratiestromen kunnen zijnbidirectioneel, deze aanroep geeft aan dat deze specifieke pijp een manier is.

4.6. Onze integratiestroom activeren

Als we al onze componenten hebben toegevoegd, moeten we dat doen registreer onze IntegrationFlow als boon om het te activeren:

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

De krijgen methode extraheert een IntegrationFlow bijvoorbeeld dat we ons moeten registreren als Spring Bean.

Zodra onze applicatiecontext wordt geladen, bevatten al onze componenten in onze IntegrationFlow wordt geactiveerd.

En nu zal onze applicatie beginnen met het verplaatsen van bestanden van de bronmap naar de doelmap.

5. Aanvullende componenten

In onze op DSL gebaseerde applicatie voor het verplaatsen van bestanden hebben we een inkomende kanaaladapter, een berichtenfilter en een serviceactivator gemaakt.

Laten we eens kijken naar een paar andere veelvoorkomende Spring Integration-componenten en kijken hoe we ze zouden kunnen gebruiken.

5.1. Berichtkanalen

Zoals eerder vermeld, een Berichtkanaal is een andere manier om een ​​stroom te initialiseren:

IntegrationFlows.from ("anyChannel")

We kunnen dit lezen als “zoek of maak een kanaalboon met de naam elk kanaal. Lees vervolgens alle gegevens die zijn ingevoerd elk kanaal uit andere stromen. "

Maar eigenlijk is het meer algemeen van toepassing dan dat.

Simpel gezegd, een kanaal abstraheert producenten van consumenten, en we kunnen het zien als een Java Wachtrij. Een kanaal kan op elk punt in de stroom worden ingevoegd.

Laten we bijvoorbeeld zeggen dat we prioriteit willen geven aan de bestanden wanneer ze van de ene map naar de volgende worden verplaatst:

@Bean public PriorityChannel alfabetisch () {retourneer nieuw PriorityChannel (1000, (links, rechts) -> ((Bestand) left.getPayload ()). GetName (). CompareTo (((File) right.getPayload ()). GetName ())); }

Vervolgens kunnen we een aanroeping invoegen naar kanaal tussen onze stroom in:

@Bean openbare IntegrationFlow fileMover () {retourneer IntegrationFlows.from (sourceDirectory ()) .filter (onlyJpgs ()) .channel ("alfabetisch") .handle (targetDirectory ()) .get (); }

Er zijn tientallen kanalen om uit te kiezen, enkele van de handigere zijn voor gelijktijdigheid, auditing of tussentijdse persistentie (denk aan Kafka- of JMS-buffers).

Ook kunnen kanalen krachtig zijn in combinatie met Brugs.

5.2. Brug

Als we dat willen combineer twee kanalengebruiken we een Brug.

Laten we ons voorstellen dat in plaats van rechtstreeks naar een uitvoermap te schrijven, we in plaats daarvan onze app voor het verplaatsen van bestanden naar een ander kanaal lieten schrijven:

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

Nu, omdat we het gewoon naar een kanaal hebben geschreven, we kunnen van daaruit overbruggen naar andere stromen.

Laten we een brug maken die onze opslagtank controleert op berichten en deze naar een bestemming schrijft:

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

Nogmaals, omdat we naar een tussenliggend kanaal hebben geschreven, kunnen we nu een andere stroom toevoegen die dezelfde bestanden gebruikt en ze met een andere snelheid schrijft:

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

Zoals we kunnen zien, kunnen individuele bridges de pollingconfiguratie voor verschillende handlers besturen.

Zodra onze toepassingscontext is geladen, hebben we nu een complexere app in actie die bestanden gaat verplaatsen van de bronmap naar twee doelmappen.

6. Conclusie

In dit artikel hebben we verschillende manieren gezien om de Spring Integration Java DSL te gebruiken om verschillende integratiepijplijnen te bouwen.

In wezen waren we in staat om de applicatie voor het verplaatsen van bestanden opnieuw te maken vanuit een eerdere zelfstudie, deze keer met pure Java.

We hebben ook een paar andere componenten bekeken, zoals kanalen en bruggen.

De volledige broncode die in deze tutorial wordt gebruikt, is beschikbaar op Github.


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