Introdução à Integração Spring
*1. Introdução *
Este artigo* apresentará os conceitos principais da Integração com a Spring *principalmente por meio de pequenos exemplos práticos.
O Spring Integration fornece muitos componentes poderosos que podem aprimorar bastante a interconectividade de sistemas e processos em uma arquitetura corporativa.
Ele incorpora alguns dos melhores e mais populares padrões de design, ajudando os desenvolvedores a evitarem criar seus próprios.
Vamos dar uma olhada nas necessidades específicas que essa biblioteca atende a um aplicativo corporativo e por que é aconselhável em algumas de suas alternativas. Também examinaremos algumas ferramentas disponíveis para simplificar ainda mais o desenvolvimento de aplicativos baseados no Spring Integration.
===* 2. Configuração *
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-file</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
Você pode fazer o download das versões mais recentes do Spring Integration Core e da https://search. maven.org/classic/#search%7Cga%7C1%7Cspring-integration-file[Suporte de arquivo de integração de primavera] do Maven Central.
===* 3. O padrão de mensagens *
Um dos padrões fundamentais nesta biblioteca é o Messaging. O padrão é centrado em mensagens - cargas úteis discretas de dados que passam de um sistema ou processo de origem para um ou vários sistemas ou processos por meio de canais predefinidos.
Historicamente, o padrão surgiu como a maneira mais flexível de integrar vários sistemas diferentes de uma maneira que:
-
Quase completamente dissocia os sistemas envolvidos na integração
-
Permite que os sistemas participantes da integração sejam completamente independentes dos protocolos, formatação ou outros detalhes de implementação subjacentes *Incentiva o desenvolvimento e a reutilização de componentes envolvidos na integração
===* 4. Integração de mensagens em ação *
Vamos considerar* um exemplo básico * que copia um arquivo de vídeo MPEG de uma pasta designada para outra pasta configurada:
@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<File> 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;
}
}
O código acima configura um ativador de serviço, um canal de integração e um adaptador de canal de entrada.
Examinaremos cada um desses tipos de componentes com mais detalhes em breve. A anotação _ @ EnableIntegration_ designa essa classe como uma configuração do Spring Integration.
Vamos começar nosso contexto de aplicativo 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 <enter> to exit the program: ");
while (true) {
String input = scanner.nextLine();
if("q".equals(input.trim())) {
break;
}
}
System.exit(0);
}
O principal método acima inicia o contexto de integração; também aceita a entrada de caracteres "q" na linha de comando para sair do programa. Vamos examinar os componentes com mais detalhes.
5. *Componentes de integração de primavera *
====* 5.1. Mensagem*
A interface org.springframework.integration.Message define a mensagem Spring: a unidade de transferência de dados em um contexto do Spring Integration.
public interface Message<T> {
T getPayload();
MessageHeaders getHeaders();
}
Ele define os acessadores para dois elementos principais:
-
Cabeçalhos de mensagens, essencialmente um contêiner de valor-chave que pode ser usado para transmitir metadados, conforme definido na classe org.springframework.integration.MessageHeaders *A carga útil da mensagem, que são os dados reais que devem ser transferidos - no nosso caso de uso, o arquivo de vídeo é a carga útil
====* 5.2 Canal *
Um canal no Spring Integration (e, de fato, EAI) é o encanamento básico em uma arquitetura de integração. É o canal pelo qual as mensagens são transmitidas de um sistema para outro.
Você pode pensar nisso como um canal literal através do qual um sistema ou processo integrado pode enviar mensagens para (ou receber mensagens de) outros sistemas.
Os canais do Spring Integration são de vários sabores, dependendo da sua necessidade. Eles são amplamente configuráveis e utilizáveis imediatamente, sem nenhum código personalizado, mas se você tiver necessidades personalizadas, há uma estrutura robusta disponível.
Os canais* ponto a ponto (P2P) *são usados para estabelecer linhas de comunicação 1 para 1 entre sistemas ou componentes. Um componente publica uma mensagem no canal para que outro possa buscá-la. Pode haver apenas um componente em cada extremidade do canal.
Como vimos, configurar um canal é tão simples quanto retornar uma instância de DirectChannel:
@Bean
public MessageChannel fileChannel1() {
return new DirectChannel();
}
@Bean
public MessageChannel fileChannel2() {
return new DirectChannel();
}
@Bean
public MessageChannel fileChannel3() {
return new DirectChannel();
}
Aqui, definimos três canais separados, todos identificados pelo nome de seus respectivos métodos getter.
Os canais Publish-Subscribe (Pub-Sub) são usados para estabelecer uma linha de comunicação um para muitos entre sistemas ou componentes. Isso nos permitirá publicar em todos os três canais diretos que criamos anteriormente.
Então, seguindo o nosso exemplo, podemos substituir o canal P2P por um canal pub-sub:
@Bean
public MessageChannel pubSubFileChannel() {
return new PublishSubscribeChannel();
}
@Bean
@InboundChannelAdapter(value = "pubSubFileChannel", poller = @Poller(fixedDelay = "1000"))
public MessageSource<File> fileReadingMessageSource() {
FileReadingMessageSource sourceReader = new FileReadingMessageSource();
sourceReader.setDirectory(new File(INPUT_DIR));
sourceReader.setFilter(new SimplePatternFileListFilter(FILE_PATTERN));
return sourceReader;
}
Agora convertemos o adaptador de canal de entrada para publicar em um canal Pub-Sub. Isso nos permitirá enviar os arquivos que estão sendo lidos da pasta de origem para vários destinos.
====* 5.3. Ponte *
Uma ponte no Spring Integration é usada para conectar dois canais de mensagem ou adaptadores, se por algum motivo eles não puderem se conectar diretamente.
No nosso caso, podemos usar uma ponte para conectar nosso canal Pub-Sub a três canais P2P diferentes (porque os canais P2P e Pub-Sub não podem ser conectados diretamente):
@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();
}
A configuração do bean acima agora une o pubSubFileChannel a três canais P2P. A anotação _ @ BridgeFrom_ é o que define uma ponte e pode ser aplicada a qualquer número de canais que precisam se inscrever no canal Pub-Sub.
Podemos ler o código acima como "criar uma ponte do pubSubFileChannel para fileChannel1, fileChannel2 e fileChannel3 para que as mensagens do pubSubFileChannel possam ser alimentadas nos três canais simultaneamente".
====* 5.4 Ativador de Serviço *
O Service Activator é qualquer POJO que define a anotação _ @ ServiceActivator_ em um determinado método. Isso nos permite executar qualquer método em nosso POJO quando uma mensagem é recebida de um canal de entrada e permite gravar mensagens em um canal de saída.
Em nosso exemplo, nosso ativador de serviço recebe um arquivo do input channel configurado e o grava na pasta configurada.
====* 5.5. Adaptador*
O adaptador é um componente baseado em padrão de integração corporativa que permite "plug-in" em um sistema ou fonte de dados. É quase literalmente um adaptador, como o conhecemos, ao conectar a uma tomada de parede ou dispositivo eletrônico.
Permite conectividade reutilizável para sistemas de "caixa preta", como bancos de dados, servidores FTP e sistemas de mensagens como JMS, AMQP e redes sociais como o Twitter. A onipresença da necessidade de conexão com esses sistemas significa que os adaptadores são muito portáteis e reutilizáveis (na verdade, há um pequeno https://docs.spring.io/spring-integration/docs/5.1.0.M1/reference/html/endpoint-summary.html [catálogo de adaptadores], disponível gratuitamente e pronto para uso por qualquer pessoa).
Os adaptadores se enquadram em duas grandes categorias - entrada e saída.
Vamos examinar essas categorias no contexto dos adaptadores em uso em nosso cenário de amostra:
*Adaptadores de entrada* , como vimos, são usados para trazer mensagens do sistema externo (neste caso, um diretório do sistema de arquivos).
Nossa configuração do adaptador de entrada consiste em:
-
Uma anotação _ @ InboundChannelAdapter_ que marca a configuração do bean como um adaptador - configuramos o canal no qual o adaptador alimentará suas mensagens (no nosso caso, um arquivo MPEG) e um poller, um componente que ajuda o adaptador a pesquisar a pasta configurada em o intervalo especificado
-
Uma classe de configuração Java padrão da Spring que retorna um _FileReadingMessageSource, _ a implementação da classe Spring Integration que lida com a pesquisa do sistema de arquivos
*Adaptadores de saída* são usados para enviar mensagens para o exterior. O Spring Integration suporta uma grande variedade de adaptadores prontos para uso para vários casos de uso comuns.
6. Conclusão
Examinamos um caso de uso básico com o Spring Integration que demonstra a configuração baseada em java da biblioteca e a reutilização dos componentes disponíveis.
O código do Spring Integration é implementável como um projeto independente no JavaSE, bem como parte de algo maior em um ambiente JavaEE. Embora não concorra diretamente com outros produtos e padrões centrados no EAI, como Enterprise Service Buses (ESBs), é uma alternativa viável e leve para resolver muitos dos mesmos problemas que os ESBs foram criados para resolver.
Você pode encontrar o código fonte deste artigo no projeto Github.