Database
 sql >> Database >  >> RDS >> Database

Che cos'è l'integrazione di primavera?

Spring fornisce supporto per l'integrazione delle applicazioni nei framework aziendali utilizzando un'estensione denominata Spring Integration . L'obiettivo principale è facilitare le applicazioni con diversi domini aziendali; le tecnologie contribuiscono all'interoperabilità orizzontale all'interno dell'impresa. Aggiunge messaggistica leggera e integrazione con sistemi e servizi esterni utilizzando un framework adattatore. Questo articolo mira a fornire una comprensione di base dell'integrazione di Spring e di come si estende al modello di programmazione Spring.

Panoramica

Le applicazioni commerciali non sono altro che soluzioni ai problemi posti dalle business unit. L'entità e la complessità dei problemi determina se la soluzione è su scala aziendale o solo poche righe di codice. Il problema con l'applicazione aziendale è che, a volte, una parte della soluzione è già disponibile utilizzando tecnologie meno recenti che potrebbero non essere convenienti da ricostruire da zero per adattarsi alle tecnologie più recenti, che si tratti di nuovo hardware o software. Questo è un problema tipico con le applicazioni legacy. Pertanto, ciò che possiamo fare è creare componenti più nuovi che interagiscano con il sistema esistente. Questa è integrazione dell'applicazione . Tuttavia, il problema non finisce qui. Non è molto facile creare componenti che funzionino perfettamente con i componenti esistenti senza imporre inutili restrizioni all'efficienza reciproca. C'è una seria considerazione che deve essere affrontata per una perfetta integrazione di più componenti. Spring Integration prende in considerazione questi problemi e fornisce agli sviluppatori un ambiente per programmare per una facile integrazione. Spring identifica i modelli comuni coinvolti e fa il lavoro con un piccolo intervento da parte degli sviluppatori.

Attacco allentato

Poiché la soluzione deve utilizzare più parti, ciascuna parte deve avere problemi separati il ​​più liberamente possibile. L'evoluzione di un componente non deve porre gravi implicazioni progettuali e manutentive su un altro. Una situazione completamente disaccoppiata non è adatta per l'integrazione, né è accettabile un accoppiamento stretto. Pertanto, il gioco consiste nel progettare il componente in un modo il più liberamente accoppiato possibile. Ci sono un paio di modi per ridurre l'accoppiamento in un'applicazione Spring:inserimento delle dipendenze o architettura guidata dagli eventi . L'architettura basata sugli eventi è un termine ampio e presenta una differenza molto sottile tra l'architettura basata sui messaggi o MOM. Sebbene non siano gli stessi tecnicamente, a questo scopo, possiamo utilizzare i termini in modo intercambiabile qui. Solo per il bene del purista, la differenza fondamentale tra guidato dagli eventi e guidato dai messaggi è che i messaggi hanno indirizzato i destinatari mentre gli eventi non sono diretti; in caso contrario, la loro attuazione difficilmente ha una chiara demarcazione. Non entriamo in questo qui; invece, concentriamoci su come viene utilizzata l'architettura basata sugli eventi con Spring Integration.

Integrazione primaverile guidata dagli eventi

Nell'architettura basata sugli eventi, un'applicazione complessa è suddivisa in diversi componenti del servizio. Questi componenti interagiscono tramite eventi generati da altri componenti, chiamati editore di eventi. Altri componenti interessati a quel particolare evento si iscrivono ad esso e in risposta intraprendono l'azione appropriata. Questo, in sostanza, è il modello editore-abbonato di lavorare sugli eventi.

Uno specifico cambiamento di stato è un evento. Come detto, un evento viene inviato alle parti interessate e gli iscritti all'evento possono scegliere di rispondere fornendo un servizio come l'esecuzione di un processo aziendale, la pubblicazione di un altro evento o, magari, ignorandolo completamente. Ciò significa che gli eventi, una volta pubblicati, non hanno alcuna responsabilità sulla risposta degli iscritti. Questo è uno scenario disaccoppiato e l'architettura basata su eventi sfrutta tali scenari di accoppiamento libero. L'accoppiamento sciolto è particolarmente adatto per eseguire il flusso di lavoro in tempo reale richiesto dall'integrazione a molla.

Componenti di integrazione primaverile

Come estensione del framework Spring, Spring Integration aggiunge fondamentalmente tre componenti:messaggi, canali di messaggi ed endpoint. Gli sviluppatori di Spring Integration hanno riconosciuto il modello comune di somiglianze per l'interazione tra varie architetture, domini e tecnologie nell'arena aziendale. Pertanto, introducendo la messaggistica tramite componenti che utilizzano pipe e filtri, questo modello è diventato la base per l'integrazione dell'applicazione. I componenti del filtro consumano o producono i messaggi mentre i tubi vengono chiamati canali in Spring Integration, descrive il flusso di messaggi tra i filtri.

Ci sono molte complessità coinvolte. Fare riferimento ai collegamenti nella sezione Riferimenti per maggiori dettagli. Qui, concentriamoci invece su una semplice implementazione con DirectChannel .

Un rapido esempio

L'esempio nel Listato 1 è un'applicazione Spring BOOT che implementa l'integrazione Spring con DirectChannel . Qui, il canale dei messaggi viene utilizzato per disaccoppiare gli endpoint dell'editore e dell'abbonato. Il canale dei messaggi viene utilizzato per stabilire la connessione con i componenti del filtro e dell'adattatore. L'esempio è piuttosto semplice e utilizza DirectChannel con modelli di comunicazione editore-abbonato e punto-punto. Nota che il codice è rudimentale e rappresenta una semplice implementazione per illustrare l'idea dell'integrazione primaverile.

<?xml version="1.0" encoding="UTF-8"?>
<project 
      xmlns_xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi_schemaLocation="http://maven.apache.org/POM/4.0.0
      http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.mano.example</groupId>
   <artifactId>spring-integration</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>
   <name>spring-integration</name>
   <description>Demo project for Spring BOOT</description>
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.0.6.RELEASE</version>
      <relativePath/> <!-- look up parent from
         repository -->
   </parent>
   <properties>
      <project.build.sourceEncoding>
         UTF-8
      </project.build.sourceEncoding>
      <project.reporting.outputEncoding>
         UTF-8
      </project.reporting.outputEncoding>
      <java.version>1.8</java.version>
   </properties>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>
            spring-boot-starter-integration
         </artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>
            spring-boot-starter-test
         </artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>
   <build>
      <plugins>
         <plugin>
            <groupId>
               org.springframework.boot
            </groupId>
            <artifactId>
               spring-boot-maven-plugin
            </artifactId>
         </plugin>
      </plugins>
   </build>
</project>

Listato 1: pom.xml, dipendenze Spring BOOT per una soluzione di integrazione Spring

package com.mano.example.springintegration.model;
import java.util.Date;
public class Tweet {
   private long tid;
   private String text;
   private Date time;
   private String hashTag;
   @Override
   public String toString() {
      return "Tweet{" +
         "tid=" + tid +
         ", text='" + text + ''' +
         ", time=" + time +
         ", hashTag='" + hashTag + ''' +
         '}';
   }
   public long getTid() {
      return tid;
   }
   public void setTid(long tid) {
      this.tid = tid;
   }
   public String getText() {
      return text;
   }
   public void setText(String text) {
      this.text = text;
   }
   public Date getTime() {
      return time;
   }
   public void setTime(Date time) {
      this.time = time;
   }
   public String getUser() {
      return hashTag;
   }
   public void setUser(String hashTag) {
      this.hashTag = hashTag;
   }
}

Listato 2: Tweet.java, classe modello

package com.mano.example.springintegration.repo;
import com.mano.example.springintegration.model.Tweet;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Component
public class TweetPublisher {
   private static long id;
   public List<Tweet> getTweets(){
      List<Tweet> tweets = new ArrayList<>();
      tweets.add(createTweet("Storms in Pacific","#weather"));
      tweets.add(createTweet("what's up developers?","#dev"));
      tweets.add(createTweet("Chinese delicacy in Amazon",
         "#traveller"));
      tweets.add(createTweet("inflation down by 2%","#stock"));
      tweets.add(createTweet("save river","#environment"));
      tweets.add(createTweet("New star found","#astronaut"));
      tweets.add(createTweet("Learn math quickly","#tutor"));
      tweets.add(createTweet("Save animals","#bovine"));
      tweets.add(createTweet("stars are favorable now",
         "#astro"));
      tweets.add(createTweet("social unrest in the world",
         "#concern"));
      return tweets;
   }
   Tweet createTweet(String text, String hashTag){
      Tweet tweet = new Tweet();
      tweet.setTid(id++);
      tweet.setUser(hashTag);
      tweet.setText(text);
      tweet.setTime(new Date());
      return tweet;
   }
}

Listato 3: TweetPublisher.java, popola i dati dei tweet

package com.mano.example.springintegration.pub;
import com.mano.example.springintegration.model.Tweet;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.support
   .MessageBuilder;
import org.springframework.stereotype.Component;
@Component
public class Tweeter {
   private DirectChannel channel;
   @Value("#{tweetChannel}")
   public void setChannel(DirectChannel channel) {
      this.channel = channel;
   }
   public void sendTweetReaders(Tweet tweet) {
      System.out.println("New Tweet - " + tweet.toString());
      channel.send(MessageBuilder.withPayload(tweet)
         .build());
   }
}

Listato 4: Tweeter.java, classe editore

package com.mano.example.springintegration.sub;
import com.mano.example.springintegration.model.Tweet;
import org.springframework.integration
   .MessageRejectedException;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.stereotype.Component;
@Component
public class TweetReader implements MessageHandler {
   @Override
   public void handleMessage(Message<?> message)
         throws MessagingException {
      Object payload = message.getPayload();
      if (payload instanceof Tweet) {
         receiveAndAcknowledge((Tweet) payload);
      } else {
        throw new MessageRejectedException(message,
           "Unknown data type has been received.");
      }
   }
   void receiveAndAcknowledge(Tweet tweet) {
      System.out.println("Hi Tweeter, this is Reader #"
         + System.identityHashCode(this) +
         "." + "Received tweet - " + tweet.toString()
         + "n");
   }
}

Listato 5: TweetReader.java, classe abbonati

package com.mano.example.springintegration;
import com.mano.example.springintegration.incoming
   .TweetPublisher;
import com.mano.example.springintegration.model.Tweet;
import com.mano.example.springintegration.pub.Tweeter;
import com.mano.example.springintegration.sub.TweetReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure
   .SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.messaging.MessageChannel;
import java.util.List;
@SpringBootApplication
@ComponentScan(basePackages = "com.mano.example.springintegration")
public class SpringIntegrationApplication {

   @Autowired
   private TweetPublisher tweetPublisher;
   @Autowired
   private Tweeter tweeter;
   @Autowired
   private DirectChannel channel;
   @Bean
   public MessageChannel tweetChannel(){
      return new DirectChannel();
   }
   @Bean
   public CommandLineRunner commandLineRunner
         (ApplicationContext context){
      return args -> {
         channel.subscribe(new TweetReader());
         channel.subscribe(new TweetReader());
         channel.subscribe(new TweetReader());
         List<Tweet> tweets = tweetPublisher.getTweets();
         for (Tweet tweet: tweets){
            tweeter.sendTweetReaders(tweet);
         }
      };
   }

   public static void main(String[] args) {
      SpringApplication.run(SpringIntegrationApplication
         .class, args);
   }
}

Listato 6: SpringIntegrationApplication.java, classe dell'applicazione principale

Conclusione

Nota che c'è molto di più con Spring Integration di quanto illustrato qui. È solo la punta dell'iceberg. I dettagli importanti sono omessi. Fare riferimento alla documentazione di Spring per maggiori dettagli su questo; i collegamenti sono riportati di seguito. Spring Integration presenta vantaggi, come Inversion of Control (IoC), programmazione orientata agli aspetti per affrontare problemi trasversali e altri vantaggi fondamentali di Spring Framework a sua disposizione. Spring Integration va oltre. Gli sviluppatori di Spring Integration non hanno bisogno di sapere come, quando e dove si trovano i dati. Il framework gestisce il modo in cui la logica di business deve essere eseguita manovrando il messaggio attraverso componenti appropriati. Oltre a un normale schema di configurazione XML, gli avviatori Spring BOOT forniscono le dipendenze necessarie per avviare il codice senza preoccuparsi delle dipendenze.

Riferimenti

  • Panoramica sull'integrazione della primavera
  • Integrazione primaverile