Introduction à l'intégration Spring

1. Introduction

Cet article présentera les concepts de base de Spring Integration principalement à travers de petits exemples pratiques.

Spring Integration fournit de nombreux composants puissants qui peuvent considérablement améliorer l'interconnectivité des systèmes et des processus au sein d'une architecture d'entreprise.

Il incarne certains des modèles de conception les plus fins et les plus populaires, aidant les développeurs à éviter de créer les leurs.

Nous examinerons les besoins spécifiques que cette bibliothèque remplit dans une application d'entreprise et pourquoi elle est recommandée par rapport à certaines de ses alternatives. Nous examinerons également certains outils disponibles pour simplifier davantage le développement d'applications basées sur Spring Integration.

2. Configuration

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

Vous pouvez télécharger les dernières versions de Spring Integration Core et de Spring Integration File Support à partir de Maven Central.

3. Le modèle de messagerie

La messagerie est l'un des modèles fondamentaux de cette bibliothèque. Le modèle est centré sur les messages - des charges utiles discrètes de données qui passent d'un système ou d'un processus d'origine à un ou plusieurs systèmes ou processus via des canaux prédéfinis.

Historiquement, le modèle est apparu comme le moyen le plus flexible d'intégrer plusieurs systèmes disparates de manière à:

  • Découple presque complètement les systèmes impliqués dans l'intégration
  • Permet aux systèmes participants à l'intégration d'être complètement indépendants les uns des autres des protocoles sous-jacents, du formatage ou d'autres détails de mise en œuvre
  • Encourage le développement et la réutilisation des composants impliqués dans l'intégration

4. Intégration de la messagerie en action

Prenons un exemple de base qui copie un fichier vidéo MPEG d'un dossier désigné vers un autre dossier configuré:

@Configuration @EnableIntegration public class BasicIntegrationConfig{ public String INPUT_DIR = "the_source_dir"; public String OUTPUT_DIR = "the_dest_dir"; public String FILE_PATTERN = "*.mpeg"; @Bean public MessageChannel fileChannel() { return new DirectChannel(); } @Bean @InboundChannelAdapter(value = "fileChannel", poller = @Poller(fixedDelay = "1000")) public MessageSource fileReadingMessageSource() { FileReadingMessageSource sourceReader= new FileReadingMessageSource(); sourceReader.setDirectory(new File(INPUT_DIR)); sourceReader.setFilter(new SimplePatternFileListFilter(FILE_PATTERN)); return sourceReader; } @Bean @ServiceActivator(inputChannel= "fileChannel") public MessageHandler fileWritingMessageHandler() { FileWritingMessageHandler handler = new FileWritingMessageHandler(new File(OUTPUT_DIR)); handler.setFileExistsMode(FileExistsMode.REPLACE); handler.setExpectReply(false); return handler; } }

Le code ci-dessus configure un activateur de service, un canal d'intégration et un adaptateur de canal entrant.

Nous examinerons bientôt chacun de ces types de composants plus en détail. L' annotation @EnableIntegration désigne cette classe comme une configuration Spring Integration.

Commençons notre contexte d'application Spring Integration:

public static void main(String... args) { AbstractApplicationContext context = new AnnotationConfigApplicationContext(BasicIntegrationConfig.class); context.registerShutdownHook(); Scanner scanner = new Scanner(System.in); System.out.print("Please enter q and press  to exit the program: "); while (true) { String input = scanner.nextLine(); if("q".equals(input.trim())) { break; } } System.exit(0); }

La méthode principale ci-dessus démarre le contexte d'intégration; il accepte également l' entrée de caractère « q » à partir de la ligne de commande pour quitter le programme. Examinons les composants plus en détail.

5. Composants d'intégration Spring

5.1. Message

L' interface org.springframework.integration.Message définit le Spring Message: l'unité de transfert de données dans un contexte Spring Integration.

public interface Message { T getPayload(); MessageHeaders getHeaders(); }

Il définit les accesseurs à deux éléments clés:

  • En-têtes de message, essentiellement un conteneur clé-valeur pouvant être utilisé pour transmettre des métadonnées, comme défini dans la classe org.springframework.integration.MessageHeaders
  • La charge utile du message, qui correspond aux données réelles qui ont une valeur à transférer - dans notre cas d'utilisation, le fichier vidéo est la charge utile

5.2. Canal

Un canal dans Spring Integration (et en fait, EAI) est la plomberie de base dans une architecture d'intégration. C'est le canal par lequel les messages sont relayés d'un système à un autre.

Vous pouvez le considérer comme un canal littéral par lequel un système ou un processus intégré peut envoyer des messages vers (ou recevoir des messages) d'autres systèmes.

Les canaux dans Spring Integration sont disponibles en différentes versions, en fonction de vos besoins. Ils sont en grande partie configurables et utilisables prêts à l'emploi, sans code personnalisé, mais si vous avez des besoins personnalisés, un cadre robuste est disponible.

Les canaux point à point (P2P) sont utilisés pour établir des lignes de communication 1 à 1 entre les systèmes ou les composants. Un composant publie un message sur le canal afin qu'un autre puisse le récupérer. Il ne peut y avoir qu'un seul composant à chaque extrémité du canal.

Comme nous l'avons vu, configurer un canal est aussi simple que de renvoyer une instance de DirectChannel :

@Bean public MessageChannel fileChannel1() { return new DirectChannel(); } @Bean public MessageChannel fileChannel2() { return new DirectChannel(); } @Bean public MessageChannel fileChannel3() { return new DirectChannel(); }

Ici, nous avons défini trois canaux distincts, tous identifiés par le nom de leurs méthodes getter respectives.

Les canaux de publication-abonnement (Pub-Sub) sont utilisés pour établir une ligne de communication un-à-plusieurs entre les systèmes ou les composants. Cela nous permettra de publier sur les 3 canaux directs que nous avons créés précédemment.

Donc, en suivant notre exemple, nous pouvons remplacer le canal P2P par un canal pub-sub:

@Bean public MessageChannel pubSubFileChannel() { return new PublishSubscribeChannel(); } @Bean @InboundChannelAdapter(value = "pubSubFileChannel", poller = @Poller(fixedDelay = "1000")) public MessageSource fileReadingMessageSource() { FileReadingMessageSource sourceReader = new FileReadingMessageSource(); sourceReader.setDirectory(new File(INPUT_DIR)); sourceReader.setFilter(new SimplePatternFileListFilter(FILE_PATTERN)); return sourceReader; } 

Nous avons maintenant converti l'adaptateur de canal entrant pour le publier sur un canal Pub-Sub. Cela nous permettra d'envoyer les fichiers en cours de lecture depuis le dossier source vers plusieurs destinations.

5.3. Pont

Un pont dans Spring Integration est utilisé pour connecter deux canaux de messages ou adaptateurs si, pour une raison quelconque, ils ne peuvent pas se connecter directement.

In our case, we can use a bridge to connect our Pub-Sub channel to three different P2P channels (because P2P and Pub-Sub channels can't be connected directly):

@Bean @BridgeFrom(value = "pubSubFileChannel") public MessageChannel fileChannel1() { return new DirectChannel(); } @Bean @BridgeFrom(value = "pubSubFileChannel") public MessageChannel fileChannel2() { return new DirectChannel(); } @Bean @BridgeFrom(value = "pubSubFileChannel") public MessageChannel fileChannel3() { return new DirectChannel(); }

The above bean configuration now bridges the pubSubFileChannel to three P2P channels. The @BridgeFrom annotation is what defines a bridge and can be applied to any number of channels that need to subscribe to the Pub-Sub channel.

We can read the above code as “create a bridge from the pubSubFileChannel to fileChannel1, fileChannel2, and fileChannel3 so that messages from pubSubFileChannel can be fed to all three channels simultaneously.”

5.4. Service Activator

The Service Activator is any POJO that defines the @ServiceActivator annotation on a given method. This allows us to execute any method on our POJO when a message is received from an inbound channel, and it allows us to write messages to an outward channel.

In our example, our service activator receives a file from the configured input channel and writes it to the configured folder.

5.5. Adapter

The Adapter is an enterprise integration pattern-based component that allows one to “plug-in” to a system or data source. It is almost literally an adapter as we know it from plugging into a wall socket or electronic device.

It allows reusable connectivity to otherwise “black-box” systems like databases, FTP servers and messaging systems such as JMS, AMQP, and social networks like Twitter. The ubiquity of the need to connect to these systems means that adapters are very portable and reusable (in fact there's a small catalog of adapters, freely available and ready to use by anyone).

Adapters fall into two broad categories — inbound and outbound.

Let's examine these categories in the context of the adapters in use in our sample scenario:

Inbound adapters, as we have seen, are used to bring in messages from the external system (in this case a filesystem directory).

Our inbound adapter configuration consists of:

  • An @InboundChannelAdapter annotation that marks the bean configuration as an adapter — we configure the channel to which the adapter will feed its messages (in our case, an MPEG file) and a poller, a component which helps the adapter poll the configured folder at the specified interval
  • A standard Spring java configuration class that returns a FileReadingMessageSource, the Spring Integration class implementation that handles filesystem polling

Outbound adapters are used to send messages outwards. Spring Integration supports a large variety of out-of-the-box adapters for various common use cases.

6. Conclusion

Nous avons examiné un cas d'utilisation de base avec Spring Integration qui démontre la configuration Java de la bibliothèque et la réutilisabilité des composants disponibles.

Le code Spring Integration est déployable en tant que projet autonome dans JavaSE ainsi que dans le cadre de quelque chose de plus grand dans un environnement Jakarta EE. Bien qu'il ne soit pas directement en concurrence avec d'autres produits et modèles centrés sur EAI tels que les bus de service d'entreprise (ESB), il s'agit d'une alternative viable et légère pour résoudre bon nombre des problèmes que les ESB ont été conçus pour résoudre.

Vous pouvez trouver le code source de cet article dans le projet Github.