Database
 sql >> Base de Dados >  >> RDS >> Database

O que é Integração Spring?


O Spring fornece suporte para integração de aplicativos em estruturas corporativas usando uma extensão chamada Spring Integration . O objetivo principal é facilitar aplicativos com diversos domínios de negócios; tecnologias trabalham para a interoperabilidade horizontal em toda a empresa. Ele adiciona mensagens leves e integração com sistemas e serviços externos usando uma estrutura de adaptador. Este artigo tem como objetivo fornecer uma compreensão básica da Integração Spring e como ela se estende ao longo do modelo de programação Spring.

Visão geral


Os aplicativos comerciais nada mais são do que soluções para os problemas apresentados pelas unidades de negócios. A magnitude e a complexidade dos problemas determinam se a solução é de escala corporativa ou apenas algumas linhas de código. O problema com o aplicativo corporativo é que, às vezes, uma parte da solução já está disponível usando tecnologias mais antigas que podem não ser rentáveis ​​para reconstruir do zero para combinar com tecnologias mais recentes, seja novo hardware ou software. Este é um problema típico com aplicativos legados. Portanto, o que podemos fazer é criar componentes mais novos que interagem com o sistema existente. Esta é a integração de aplicativos . No entanto, o problema não termina aí. Não é muito fácil criar componentes que funcionem perfeitamente com componentes existentes sem impor restrições desnecessárias à eficiência uns dos outros. Há uma consideração séria que deve ser abordada para a integração perfeita de vários componentes. O Spring Integration considera esses problemas e fornece um ambiente para desenvolvedores codificarem para facilitar a integração. O Spring identifica os padrões comuns envolvidos e faz o trabalho com pouca intervenção dos desenvolvedores.

Acoplamento solto


Como a solução deve usar várias partes, cada parte deve ter preocupações separadas da maneira mais fraca possível. A evolução de um componente não deve representar sérias implicações de projeto e manutenção em outro. Uma situação desacoplada completa não é adequada para integração, nem um acoplamento rígido é aceitável. Portanto, o jogo é projetar o componente da maneira mais fraca possível. Existem algumas maneiras de reduzir o acoplamento em um aplicativo Spring:injeção de dependência ou arquitetura orientada a eventos . Arquitetura orientada a eventos é um termo amplo e tem uma diferença muito tênue entre arquitetura orientada a mensagens, ou MOM. Embora tecnicamente não sejam os mesmos, para este fim, podemos usar os termos de forma intercambiável aqui. Apenas para o bem dos puristas, a diferença básica entre as mensagens orientadas por eventos e orientadas por mensagens é que as mensagens têm destinatários direcionados, enquanto os eventos não são direcionados; caso contrário, sua implementação dificilmente tem uma demarcação clara. Não vamos entrar nisso aqui; em vez disso, vamos nos concentrar em como a arquitetura orientada a eventos é utilizada com o Spring Integration.

Integração Spring orientada a eventos


Na arquitetura orientada a eventos, um aplicativo complexo é dividido em vários componentes de serviço. Esses componentes interagem por meio de eventos gerados por outros componentes, que são chamados de publisher de eventos. Outros componentes que estão interessados ​​nesse evento específico se inscrevem nele e tomam as medidas apropriadas em resposta. Esse é, em essência, o modelo editor-assinante de trabalhar em eventos.

Uma mudança específica no estado é um evento. Conforme declarado, um evento é enviado aos interessados ​​e os assinantes do evento podem optar por responder fornecendo um serviço como executar um processo de negócios, publicar outro evento ou, talvez, ignorá-lo completamente. Isso significa que os eventos, uma vez publicados, não têm qualquer responsabilidade sobre a resposta dos assinantes. Este é um cenário desacoplado e a arquitetura orientada a eventos aproveita esses cenários de acoplamento fraco. O acoplamento solto é particularmente adequado para executar o fluxo de trabalho em tempo real que o Spring Integration requer.

Componentes de integração do Spring


Como uma extensão do framework Spring, o Spring Integration adiciona basicamente três componentes:mensagens, canais de mensagens e terminais. Os desenvolvedores do Spring Integration reconheceram o padrão comum de semelhanças para interoperar entre arquiteturas, domínios e tecnologias variadas na arena corporativa. Portanto, ao introduzir a mensageria por meio de componentes usando pipes e filtro, esse modelo se tornou a base para a integração de aplicativos. Os componentes do filtro consomem ou produzem as mensagens enquanto os pipes, chamados de canais em Spring Integration, descreve o fluxo de mensagens entre filtros.

Há muitos meandros envolvidos. Consulte os links na seção Referências para obter mais detalhes. Aqui, vamos focar em uma implementação simples com DirectChannel .

Um exemplo rápido


O exemplo na Listagem 1 é um aplicativo Spring BOOT que implementa Spring Integration com DirectChannel . Aqui, o canal de mensagem é usado para desacoplar os endpoints do editor e do assinante. O canal de mensagem é usado para estabelecer conexão com os componentes de filtro e adaptador. O exemplo é bem direto e usa DirectChannel com modelos de comunicação editor-assinante e ponto a ponto. Observe que o código é rudimentar e uma implementação simples para ilustrar a ideia do 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>

Listagem 1: pom.xml, dependências do Spring BOOT para uma solução 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;
   }
}

Lista 2: Tweet.java, classe de 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;
   }
}

Listagem 3: TweetPublisher.java, preenche dados de tweets
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());
   }
}

Listagem 4: Tweeter.java, classe 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");
   }
}

Listagem 5: TweetReader.java, classe de assinante
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);
   }
}

Listagem 6: SpringIntegrationApplication.java, classe principal do aplicativo

Conclusão


Observe que há muito mais com Spring Integration do que o ilustrado aqui. É apenas a ponta do iceberg. Detalhes importantes são omitidos. Consulte a documentação do Spring para obter mais detalhes sobre isso; links são dados abaixo. Spring Integration tem vantagens, como Inversão de Controle (IoC), programação orientada a aspectos para tratar de preocupações transversais e outras vantagens centrais do Spring Framework à sua disposição. Spring Integration leva mais longe. Os desenvolvedores do Spring Integration não precisam saber como, quando e onde os dados estão. A estrutura trata como a lógica de negócios deve ser executada, manobrando a mensagem por meio de componentes apropriados. Além de um esquema de configuração XML regular, os iniciadores do Spring BOOT fornecem as dependências necessárias para iniciar o código de frente com poucas preocupações sobre dependências.

Referências

  • Visão geral da integração do Spring
  • Integração do Spring