Un exemple senzill de Spring Integration
1. Introducció
Spring Integration és un framework que ajuda a connectar sistemes dins d’una aplicació Spring. Usa les mateixes idees que els Enterprise Integration Patterns: missatges, canals i endpoints. Si ja coneixes Spring Boot, resulta familiar al cap de pocs minuts.
En aquest article mostraré un exemple mínim de «hello world». Enviarem un nom a través d’un gateway, el passarem per un canal i obtindrem una salutació.
2. Què és Spring Integration
En lloc de cridar mètodes directament, envies missatges. Un missatge té un payload i headers. El payload són les dades reals. Els headers són metadades, com un id de correlació o una marca de temps.
Tres peces principals:
- Message: l’element que viatja. Té un payload i headers.
- Channel: el conducte on els missatges esperen o es mouen. Pensa-hi com una
Queueo unaList. - Endpoint: la peça que fa alguna cosa amb el missatge. Per exemple, un
ServiceActivatorés un endpoint que executa un mètode.
3. Dependències
Afegeix spring-integration-core al projecte. Si fas servir Spring Boot, el starter ja el porta quan inclous els mòduls correctes. Per a un exemple sense més:
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
</dependency>
Si fas servir Gradle:
implementation 'org.springframework.integration:spring-integration-core'
4. L’exemple Hello World
Volem cridar sayHello("World") i obtenir "Hello, World!". La crida passa per un gateway, un canal i un service activator.
4.1 La configuració
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.messaging.MessageChannel;
@Configuration
@EnableIntegration
@IntegrationComponentScan
public class HelloIntegrationConfig {
@Bean
public MessageChannel helloChannel() {
return new DirectChannel();
}
@ServiceActivator(inputChannel = "helloChannel")
public String handle(String name) {
return "Hello, " + name + "!";
}
@MessagingGateway
public interface HelloGateway {
String sayHello(String name);
}
}
Què està passant aquí:
helloChannel()crea unDirectChannel. És un canal senzill en memòria que passa el missatge al següent endpoint immediatament.handleés unServiceActivator. EscoltahelloChannel, rep el payload com aStringi retorna unStringnou.HelloGatewayés unMessagingGateway. Spring en crea una implementació. Envia l’entrada al canal i retorna el que rep.
4.2 Com flueix el missatge
- Crides
gateway.sayHello("World"). - El gateway embolcalla
"World"en unMessagei el posa ahelloChannel. - El
ServiceActivatoragafa el payload i executahandle("World"). - El valor de retorn
"Hello, World!"es converteix en un missatge de resposta. - El gateway retorna el payload de la resposta a qui ha fet la crida.
El codi que el fa servir no sembla diferent d’una crida normal a un mètode:
HelloIntegrationConfig.HelloGateway gateway = ...;
String greeting = gateway.sayHello("World");
System.out.println(greeting); // Hello, World!
5. Provar l’exemple
Un test petit amb JUnit 5 i Spring:
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.test.context.SpringIntegrationTest;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringJUnitConfig(HelloIntegrationConfig.class)
class HelloIntegrationTest {
private HelloIntegrationConfig.HelloGateway gateway = new HelloIntegrationConfig.HelloGateway();
@Test
void shouldReturnGreeting() {
String result = gateway.sayHello("World");
assertEquals("Hello, World!", result);
}
}
Si les dependències de test no estan disponibles al projecte, també pots carregar el context amb @SpringBootTest o AnnotationConfigApplicationContext.
6. Algunes coses a tenir en compte
DirectChannelés síncron. Qui fa la crida espera que acabi el service activator. Això va bé per a exemples senzills.- Si vols gestió asíncrona, fes servir un
QueueChannel. - El tipus del payload al service activator pot ser un
String, unMessage<String>o el teu propi objecte. Spring ho resol. @MessagingGatewayevita haver de construir i enviar missatges manualment.
7. Conclusió
Aquest és l’exemple útil més petit de Spring Integration. Tens un gateway, un canal i un service activator. El gateway és l’entrada, el canal és el conducte i el service activator fa la feina. Quan això queda clar, és fàcil afegir transformers, filters, routers i adapters.
En el proper article mostraré com afegir un transformer i un router al mateix flux.