Introduktion til forårets integration

1. Introduktion

Denne artikel vil introducere kernebegreberne i Spring Integration primært gennem små, praktiske eksempler.

Spring Integration leverer mange kraftfulde komponenter, der i høj grad kan forbedre sammenkoblingen af ​​systemer og processer inden for en virksomhedsarkitektur.

Det indeholder nogle af de fineste og mest populære designmønstre, hvilket hjælper udviklere med at undgå at rulle deres egne.

Vi vil se på de specifikke behov, som dette bibliotek udfylder en virksomhedsapplikation, og hvorfor det tilrådes over nogle af dets alternativer. Vi vil også se på nogle tilgængelige værktøjer til yderligere forenkling af udviklingen af ​​Spring Integration-baserede applikationer.

2. Opsætning

 org.springframework.integration spring-integration-core 4.3.5.RELEASE org.springframework.integration spring-integration-file 4.3.5.RELEASE 

Du kan downloade de nyeste versioner af Spring Integration Core og Spring Integration File Support fra Maven Central.

3. Meddelelsesmønsteret

Et af de grundlæggende mønstre i dette bibliotek er Messaging. Mønsteret er centreret omkring meddelelser - diskrete nyttelast af data, der bevæger sig fra et oprindeligt system eller en proces til et eller flere systemer eller processer via foruddefinerede kanaler.

Historisk opstod mønsteret som den mest fleksible måde at integrere flere forskellige systemer på en måde, der:

  • Afkobler næsten helt de systemer, der er involveret i integrationen
  • Tillader deltagersystemer i integrationen at være fuldstændig agnostiske over for hinandens underliggende protokoller, formatering eller andre implementeringsoplysninger
  • Tilskynder til udvikling og genbrug af komponenter, der er involveret i integrationen

4. Integration af beskeder i aktion

Lad os overveje et grundlæggende eksempel der kopierer en MPEG-videofil fra en bestemt mappe til en anden konfigureret mappe:

@Configuration @EnableIntegration public class BasicIntegrationConfig {public String INPUT_DIR = "the_source_dir"; offentlig streng OUTPUT_DIR = "the_dest_dir"; offentlig streng FILE_PATTERN = "* .mpeg"; @Bean offentlig MessageChannel fileChannel () {returner ny DirectChannel (); } @Bean @InboundChannelAdapter (værdi = "fileChannel", poller = @Poller (fixedDelay = "1000")) offentlig MessageSource fileReadingMessageSource () {FileReadingMessageSource sourceReader = ny FileReadingMessageSource (); sourceReader.setDirectory (ny fil (INPUT_DIR)); sourceReader.setFilter (nyt SimplePatternFileListFilter (FILE_PATTERN)); return sourceReader; } @Bean @ServiceActivator (inputChannel = "fileChannel") offentlig MessageHandler fileWritingMessageHandler () {FileWritingMessageHandler handler = ny FileWritingMessageHandler (ny fil (OUTPUT_DIR)); handler.setFileExistsMode (FileExistsMode.REPLACE); handler.setExpectReply (false); returhandler }}

Koden ovenfor konfigurerer en serviceaktiver, en integrationskanal og en indgående kanaladapter.

Vi undersøger kortvarigt hver af disse komponenttyper. Det @EnableIntegration annotation betegner denne klasse som en Spring Integration-konfiguration.

Lad os starte vores Spring Integration applikationskontekst:

public static void main (String ... args) {AbstractApplicationContext context = new AnnotationConfigApplicationContext (BasicIntegrationConfig.class); context.registerShutdownHook (); Scannerscanner = ny scanner (System.in); System.out.print ("Indtast q og tryk for at afslutte programmet:"); while (true) {String input = scanner.nextLine (); if ("q" .equals (input.trim ())) {break; }} System.exit (0); }

Hovedmetoden ovenfor starter integrationskonteksten; det accepterer også “q”Tegninput fra kommandolinjen for at afslutte programmet. Lad os undersøge komponenterne mere detaljeret.

5. Fjederintegrationskomponenter

5.1. Besked

Det org.springframework.integration.Message grænsefladen definerer fjedermeddelelsen: dataenhedsenheden inden for en fjederintegrationskontekst.

offentlig grænseflade Besked {T getPayload (); MessageHeaders getHeaders (); }

Det definerer accessors til to nøgleelementer:

  • Beskedoverskrifter, i det væsentlige en nøgleværdibeholder, der kan bruges til at overføre metadata, som defineret i org.springframework.integration.MessageHeaders klasse
  • Beskedens nyttelast, som er de faktiske data, der er af værdi, der skal overføres - i vores brugssag er videofilen nyttelasten

5.2. Kanal

En kanal i Spring Integration (og faktisk EAI) er den grundlæggende VVS i en integrationsarkitektur. Det er røret, hvormed meddelelser videresendes fra et system til et andet.

Du kan tænke på det som et bogstaveligt rør, hvorigennem et integreret system eller en proces kan skubbe beskeder til (eller modtage beskeder fra) andre systemer.

Kanaler i Spring Integration findes i forskellige varianter afhængigt af dit behov. De er stort set konfigurerbare og anvendelige uden for boksen uden nogen brugerdefineret kode, men hvis du har brugerdefinerede behov, er der en robust ramme til rådighed.

Punkt til punkt (P2P) kanaler bruges til at etablere 1 til 1 kommunikationslinjer mellem systemer eller komponenter. En komponent offentliggør en besked til kanalen, så en anden kan hente den. Der kan kun være en komponent i hver ende af kanalen.

Som vi har set, er konfigurering af en kanal lige så enkel som at returnere en forekomst af DirectChannel:

@Bean offentlig MessageChannel fileChannel1 () {returner ny DirectChannel (); } @Bean public MessageChannel fileChannel2 () {returner ny DirectChannel (); } @Bean offentlig MessageChannel fileChannel3 () {returner ny DirectChannel (); }

Her har vi defineret tre separate kanaler, som alle er identificeret ved navnet på deres respektive gettermetoder.

Publicer-abonner (Pub-Sub) kanaler bruges til at etablere en en-til-mange kommunikationslinje mellem systemer eller komponenter. Dette giver os mulighed for at offentliggøre til alle de 3 direkte kanaler, som vi oprettede tidligere.

Så efter vores eksempel kan vi erstatte P2P-kanalen med en pub-sub-kanal:

@Bean offentlig MessageChannel pubSubFileChannel () {returner ny PublishSubscribeChannel (); } @Bean @InboundChannelAdapter (værdi = "pubSubFileChannel", poller = @Poller (fixedDelay = "1000")) offentlig MessageSource fileReadingMessageSource () {FileReadingMessageSource sourceReader = ny FileReadingMessageSource (); sourceReader.setDirectory (ny fil (INPUT_DIR)); sourceReader.setFilter (nyt SimplePatternFileListFilter (FILE_PATTERN)); return sourceReader; } 

Vi har nu konverteret den indgående kanaladapter til at udgive til en Pub-Sub-kanal. Dette giver os mulighed for at sende de filer, der læses fra kildemappen til flere destinationer.

5.3. Bro

En bro i Spring Integration bruges til at forbinde to meddelelseskanaler eller adaptere, hvis de af en eller anden grund ikke kan oprette forbindelse direkte.

I vores tilfælde kan vi bruge en bro til at forbinde vores Pub-Sub-kanal til tre forskellige P2P-kanaler (fordi P2P- og Pub-Sub-kanaler ikke kan forbindes direkte):

@Bean @BridgeFrom (værdi = "pubSubFileChannel") offentlig MessageChannel fileChannel1 () {returner ny DirectChannel (); } @Bean @BridgeFrom (value = "pubSubFileChannel") offentlig MessageChannel fileChannel2 () {returner ny DirectChannel (); } @Bean @BridgeFrom (værdi = "pubSubFileChannel") offentlig MessageChannel fileChannel3 () {returner ny DirectChannel (); }

Ovenstående bønnekonfiguration bygger nu bro over pubSubFileChannel til tre P2P-kanaler. Det @BridgeFrom kommentar er, hvad der definerer en bro og kan anvendes på et hvilket som helst antal kanaler, der har brug for at abonnere på Pub-Sub-kanalen.

Vi kan læse ovenstående kode som "opret en bro fra pubSubFileChannel til fileChannel1, fileChannel2 og fileChannel3 så meddelelser fra pubSubFileChannel kan tilføres til alle tre kanaler samtidigt. ”

5.4. Serviceaktivator

Serviceaktivatoren er enhver POJO, der definerer @ServiceActivator kommentar på en given metode. Dette giver os mulighed for at udføre enhver metode på vores POJO, når en besked modtages fra en indgående kanal, og det giver os mulighed for at skrive beskeder til en udadgående kanal.

I vores eksempel modtager vores serviceaktiver en fil fra det konfigurerede indgangskanal og skriver det til den konfigurerede mappe.

5.5. Adapter

Adapteren er en virksomhedsintegrationsmønsterbaseret komponent, der gør det muligt at "plug-in" til et system eller en datakilde. Det er næsten bogstaveligt talt en adapter, som vi kender det fra tilslutning til et stikkontakt eller en elektronisk enhed.

Det giver mulighed for genanvendelig forbindelse til ellers "black-box" -systemer som databaser, FTP-servere og messaging-systemer som JMS, AMQP og sociale netværk som Twitter. Den allestedsnærværende nødvendighed af at oprette forbindelse til disse systemer betyder, at adaptere er meget bærbare og genanvendelige (faktisk er der et lille katalog med adaptere, frit tilgængelige og klar til brug for alle).

Adaptere falder i to brede kategorier - indgående og udgående.

Lad os undersøge disse kategorier i sammenhæng med de adaptere, der er i brug i vores eksempelscenarie:

Indgående adaptere, som vi har set, bruges til at hente meddelelser fra det eksterne system (i dette tilfælde et filsystemkatalog).

Vores indgående adapterkonfiguration består af:

  • En @InboundChannelAdapter kommentar, der markerer bønnekonfigurationen som en adapter - vi konfigurerer den kanal, som adapteren vil føje sine meddelelser til (i vores tilfælde en MPEG-fil) og en poller, en komponent, der hjælper adapteren med at afstemme den konfigurerede mappe med det angivne interval
  • En standard Spring Java-konfigurationsklasse, der returnerer en FileReadingMessageSource, Spring Integration klasse implementering, der håndterer filsystem polling

Udgående adaptere bruges til at sende meddelelser udad. Spring Integration understøtter et stort udvalg af out-of-the-box adaptere til forskellige almindelige brugssager.

6. Konklusion

Vi har undersøgt en grundlæggende brugssag med Spring Integration, der demonstrerer den java-baserede konfiguration af biblioteket og genanvendelighed af de tilgængelige komponenter.

Spring Integration-kode kan implementeres som et enkeltstående projekt inden for JavaSE såvel som en del af noget større i et Jakarta EE-miljø. Selvom det ikke direkte konkurrerer med andre EAI-centrerede produkter og mønstre som Enterprise Service Buses (ESB'er), er det et levedygtigt, letvægtsalternativ til at løse mange af de samme problemer, som ESB'er blev bygget til at løse.

Du kan finde kildekoden til denne artikel i Github-projektet.