sql >> Base de Datos >  >> RDS >> Database

¿Qué es la integración de primavera?

Spring brinda soporte para la integración de aplicaciones en marcos empresariales mediante el uso de una extensión llamada Spring Integration . El objetivo principal es facilitar aplicaciones con diversos dominios comerciales; Las tecnologías trabajan hacia la interoperabilidad horizontal en toda la empresa. Agrega mensajería ligera e integración con sistemas y servicios externos utilizando un marco de adaptador. Este artículo tiene como objetivo proporcionar una comprensión básica de Spring Integration y cómo se extiende sobre el modelo de programación Spring.

Resumen

Las aplicaciones comerciales no son más que soluciones a los problemas planteados por las unidades de negocio. La magnitud y complejidad de los problemas determina si la solución es a escala empresarial o solo unas pocas líneas de código. El problema con la aplicación empresarial es que, a veces, una parte de la solución ya está disponible utilizando tecnologías más antiguas que pueden no ser rentables para reconstruir desde cero para que coincidan con las tecnologías más nuevas, ya sea nuevo hardware o software. Este es un problema típico con las aplicaciones heredadas. Por lo tanto, lo que podemos hacer es crear componentes más nuevos que interactúen con el sistema existente. Esto es integración de aplicaciones . Sin embargo, el problema no termina ahí. No es muy fácil crear componentes que funcionen a la perfección con los componentes existentes sin imponer restricciones innecesarias a la eficiencia de los demás. Hay una consideración seria que debe abordarse para la integración perfecta de múltiples componentes. Spring Integration considera estos problemas y proporciona un entorno para que los desarrolladores codifiquen para una fácil integración. Spring identifica los patrones comunes involucrados y hace el trabajo con poca intervención de los desarrolladores.

Acoplamiento flojo

Debido a que la solución debe usar múltiples partes, cada parte debe tener preocupaciones separadas de la manera más débil posible. La evolución de un componente no debe plantear implicaciones graves de diseño y mantenimiento en otro. Una situación de desacoplamiento completo no es apta para la integración, ni tampoco es aceptable un acoplamiento estrecho. Por lo tanto, el juego consiste en diseñar el componente de la manera más flexible posible. Hay un par de formas de reducir el acoplamiento en una aplicación Spring:inyección de dependencia o arquitectura basada en eventos . La arquitectura basada en eventos es un término amplio y tiene una diferencia muy fina entre la arquitectura basada en mensajes o MOM. Aunque técnicamente no son lo mismo, para este propósito, podemos usar los términos indistintamente aquí. Solo por el bien de los puristas, la diferencia básica entre los basados ​​en eventos y los basados ​​en mensajes es que los mensajes tienen destinatarios dirigidos mientras que los eventos no están dirigidos; de lo contrario, su implementación apenas tiene una demarcación clara. No entremos en eso aquí; en su lugar, centrémonos en cómo se utiliza la arquitectura basada en eventos con Spring Integration.

Integración Spring impulsada por eventos

En la arquitectura basada en eventos, una aplicación compleja se divide en varios componentes de servicio. Estos componentes interactúan a través de eventos generados por otros componentes, que se denominan editor de eventos. Otros componentes que están interesados ​​en ese evento en particular se suscriben y toman las medidas apropiadas en respuesta. Esto, en esencia, es el modelo editor-suscriptor de trabajar en eventos.

Un cambio específico en el estado es un evento. Como se dijo, un evento se envía a las partes interesadas y los suscriptores del evento pueden optar por responder brindando un servicio, como ejecutar un proceso comercial, publicar otro evento o, tal vez, ignorarlo por completo. Eso significa que los eventos, una vez publicados, no tienen ninguna responsabilidad sobre la respuesta de los suscriptores. Este es un escenario desacoplado y la arquitectura basada en eventos aprovecha estos escenarios de acoplamiento flexible. El acoplamiento flexible es particularmente adecuado para realizar el flujo de trabajo en tiempo real que requiere Spring Integration.

Componentes de integración de primavera

Como una extensión del marco Spring, Spring Integration básicamente agrega tres componentes:mensajes, canales de mensajes y puntos finales. Los desarrolladores de Spring Integration reconocieron el patrón común de similitudes para interoperar entre diversas arquitecturas, dominios y tecnologías en el ámbito empresarial. Por lo tanto, al introducir la mensajería a través de componentes que usan canalizaciones y filtros, este modelo se convirtió en la base para la integración de aplicaciones. Los componentes del filtro consumen o producen los mensajes mientras que las tuberías, denominadas canales en Spring Integration, describe el flujo de mensajes entre filtros.

Hay muchas complejidades involucradas. Consulte los enlaces en la sección Referencias para obtener más detalles. Aquí, centrémonos en cambio en una implementación simple con DirectChannel .

Un ejemplo rápido

El ejemplo del Listado 1 es una aplicación Spring BOOT que implementa Spring Integration con DirectChannel . Aquí, el canal de mensajes se usa para desacoplar los puntos finales del editor y del suscriptor. El canal de mensajes se utiliza para establecer la conexión con los componentes del filtro y el adaptador. El ejemplo es bastante sencillo y usa DirectChannel con modelos de comunicación editor-suscriptor y punto a punto. Tenga en cuenta que el código es rudimentario y una implementación simple para ilustrar la idea de Spring Integration.

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

Listado 1: pom.xml, dependencias Spring BOOT para una solución Spring Integration

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

Listado 2: Tweet.java, clase modelo

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

Listado 3: TweetPublisher.java, rellena los datos del 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());
   }
}

Listado 4: Tweeter.java, clase de editor

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

Listado 5: TweetReader.java, clase de suscriptor

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

Listado 6: SpringIntegrationApplication.java, clase de aplicación principal

Conclusión

Tenga en cuenta que hay mucho más con Spring Integration de lo que se ilustra aquí. Es solo la punta del iceberg. Se omiten detalles importantes. Consulte la documentación de Spring para obtener más detalles al respecto; Los enlaces se dan a continuación. Spring Integration tiene ventajas, como Inversion of Control (IoC), programación orientada a aspectos para abordar problemas transversales y otras ventajas principales de Spring Framework a su disposición. Spring Integration va más allá. Los desarrolladores de Spring Integration no necesitan saber cómo, cuándo y el paradero de los datos. El marco maneja cómo se ejecutará la lógica comercial al maniobrar el mensaje a través de los componentes apropiados. Además de un esquema de configuración XML normal, los arrancadores Spring BOOT proporcionan las dependencias necesarias para iniciar el código sin preocuparse por las dependencias.

Referencias

  • Descripción general de la integración de Spring
  • Integración de primavera