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

Was ist Frühlingsintegration?

Spring bietet Unterstützung für die Anwendungsintegration über Unternehmensframeworks hinweg, indem eine Erweiterung namens Spring Integration verwendet wird . Das Hauptziel besteht darin, Anwendungen mit unterschiedlichen Geschäftsdomänen zu erleichtern; Technologien arbeiten auf horizontale Interoperabilität im gesamten Unternehmen hin. Es fügt leichtgewichtiges Messaging und Integration mit externen Systemen und Diensten über ein Adapter-Framework hinzu. Dieser Artikel soll ein grundlegendes Verständnis der Spring-Integration vermitteln und wie sie sich auf das Spring-Programmiermodell ausdehnt.

Übersicht

Kommerzielle Anwendungen sind nichts anderes als Problemlösungen von Fachbereichen. Das Ausmaß und die Komplexität der Probleme bestimmen, ob die Lösung unternehmensweit oder nur wenige Codezeilen umfasst. Das Problem bei der Unternehmensanwendung besteht darin, dass manchmal ein Teil der Lösung bereits mit älteren Technologien verfügbar ist, die möglicherweise nicht kostengünstig von Grund auf neu erstellt werden können, um sie an neuere Technologien anzupassen, sei es neue Hardware oder Software. Dies ist ein typisches Problem bei Legacy-Anwendungen. Daher können wir neuere Komponenten erstellen, die mit dem bestehenden System zusammenarbeiten. Das ist Anwendungsintegration . Das Problem endet jedoch nicht dort. Es ist nicht sehr einfach, Komponenten zu erstellen, die nahtlos mit bestehenden Komponenten zusammenarbeiten, ohne die Effizienz der anderen unnötig einzuschränken. Es gibt eine ernsthafte Überlegung, die für die nahtlose Integration mehrerer Komponenten angegangen werden muss. Spring Integration berücksichtigt diese Probleme und bietet Entwicklern eine Umgebung zum Programmieren für eine einfache Integration. Spring identifiziert die gemeinsamen Muster und erledigt die Arbeit mit wenig Entwicklereingriff.

Lose Kupplung

Da die Lösung mehrere Teile verwenden muss, muss jeder Teil auf möglichst lose gekoppelte Weise getrennte Anliegen haben. Die Weiterentwicklung einer Komponente darf keine schwerwiegenden Auswirkungen auf Design und Wartung für eine andere haben. Eine vollständig entkoppelte Situation eignet sich nicht für eine Integration, noch ist eine enge Kopplung akzeptabel. Daher besteht das Spiel darin, das Bauteil möglichst lose gekoppelt zu gestalten. Es gibt mehrere Möglichkeiten, die Kopplung in einer Spring-Anwendung zu reduzieren:Abhängigkeitsinjektion oder ereignisgesteuerte Architektur . Ereignisgesteuerte Architektur ist ein weit gefasster Begriff und weist einen sehr feinen Unterschied zwischen nachrichtengesteuerter Architektur oder MOM auf. Obwohl sie technisch nicht gleich sind, können wir die Begriffe hier zu diesem Zweck austauschbar verwenden. Nur um der Puristen willen besteht der grundlegende Unterschied zwischen ereignisgesteuert und nachrichtengesteuert darin, dass Nachrichten gerichtete Empfänger haben, während Ereignisse ungerichtet sind; ansonsten lässt sich ihre Umsetzung kaum klar abgrenzen. Lassen Sie uns hier nicht darauf eingehen; Konzentrieren wir uns stattdessen darauf, wie ereignisgesteuerte Architektur mit Spring Integration verwendet wird.

Ereignisgesteuerte Spring-Integration

In der ereignisgesteuerten Architektur wird eine komplexe Anwendung in mehrere Dienstkomponenten zerlegt. Diese Komponenten interagieren über Ereignisse, die von anderen Komponenten generiert werden, die als Publisher bezeichnet werden von Veranstaltungen. Andere Komponenten, die an diesem bestimmten Ereignis interessiert sind, abonnieren es und ergreifen als Reaktion darauf geeignete Maßnahmen. Dies ist im Wesentlichen das Publisher-Subscriber-Modell der Arbeit an Ereignissen.

Eine bestimmte Zustandsänderung ist ein Ereignis. Wie gesagt, ein Ereignis wird an interessierte Parteien gesendet und die Ereignisabonnenten können wählen, ob sie darauf reagieren möchten, indem sie einen Geschäftsprozess ausführen, ein anderes Ereignis veröffentlichen oder es möglicherweise vollständig ignorieren. Das bedeutet, dass die einmal veröffentlichten Ereignisse keine Verantwortung für die Reaktion der Abonnenten übernehmen. Dies ist ein entkoppeltes Szenario, und die ereignisgesteuerte Architektur nutzt solche Szenarien mit lockerer Kopplung. Die lose Kopplung ist besonders geeignet, um einen Echtzeit-Arbeitsablauf auszuführen, der für die Spring-Integration erforderlich ist.

Spring-Integrationskomponenten

Als Erweiterung des Spring-Frameworks fügt Spring Integration im Wesentlichen drei Komponenten hinzu:Nachrichten, Nachrichtenkanäle und Endpunkte. Die Entwickler von Spring Integration erkannten das gemeinsame Muster von Ähnlichkeiten, um zwischen verschiedenen Architekturen, Domänen und Technologien im Unternehmensbereich zusammenzuarbeiten. Daher wurde dieses Modell durch die Einführung von Messaging über Komponenten unter Verwendung von Pipes und Filtern zur Grundlage für die Anwendungsintegration. Die Filterkomponenten konsumieren oder produzieren die Nachrichten, während die Pipes, die als Kanäle bezeichnet werden in Spring Integration, beschreibt den Nachrichtenfluss zwischen Filtern.

Es gibt viele Feinheiten beteiligt. Weitere Informationen finden Sie unter den Links im Abschnitt „Referenzen“. Konzentrieren wir uns hier stattdessen auf eine einfache Implementierung mit DirectChannel .

Ein kurzes Beispiel

Das Beispiel in Listing 1 ist eine Spring BOOT-Anwendung, die Spring Integration mit DirectChannel implementiert . Hier wird der Nachrichtenkanal verwendet, um die Endpunkte des Herausgebers und des Abonnenten zu entkoppeln. Der Nachrichtenkanal wird verwendet, um eine Verbindung mit den Filter- und Adapterkomponenten herzustellen. Das Beispiel ist ziemlich einfach und verwendet DirectChannel mit Publisher-Subscriber- und Punkt-zu-Punkt-Kommunikationsmodellen. Beachten Sie, dass der Code rudimentär und eine einfache Implementierung ist, um die Idee der Spring-Integration zu veranschaulichen.

<?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>

Auflistung 1: pom.xml, Spring BOOT-Abhängigkeiten für eine Spring-Integrationslösung

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;
   }
}

Auflistung 2: Tweet.java, Modellklasse

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;
   }
}

Auflistung 3: TweetPublisher.java, füllt Tweet-Daten

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());
   }
}

Auflistung 4: Tweeter.java, Publisher-Klasse

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");
   }
}

Auflistung 5: TweetReader.java, Abonnentenklasse

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);
   }
}

Auflistung 6: SpringIntegrationApplication.java, Hauptanwendungsklasse

Schlussfolgerung

Beachten Sie, dass Spring Integration viel mehr bietet als hier dargestellt. Es ist nur die Spitze des Eisbergs. Wichtige Details werden weggelassen. Weitere Informationen hierzu finden Sie in der Spring-Dokumentation. Links sind unten angegeben. Spring Integration verfügt über Vorteile wie Inversion of Control (IoC), aspektorientierte Programmierung zur Adressierung übergreifender Anliegen und andere Kernvorteile von Spring Framework. Spring Integration geht noch weiter. Entwickler von Spring Integration müssen das Wie, Wann und den Verbleib der Daten nicht kennen. Das Framework handhabt, wie die Geschäftslogik ausgeführt werden soll, indem es die Nachricht durch geeignete Komponenten manövriert. Abgesehen von einem regulären XML-Konfigurationsschema liefern Spring BOOT-Starter die erforderlichen Abhängigkeiten, um den Code direkt zu starten, ohne sich um Abhängigkeiten kümmern zu müssen.

Referenzen

  • Überblick über die Frühlingsintegration
  • Frühjahrsintegration