From spring
Build message-driven application flows with Spring Integration channels, routers, filters, splitters, aggregators, gateways, pollers, and protocol adapters. Use this skill when building message-driven application flows with Spring Integration using channels, routers, filters, splitters, aggregators, gateways, pollers, and protocol adapters.
npx claudepluginhub ririnto/sinon --plugin springThis skill uses the workspace's default tool permissions.
Use this skill when building message-driven application flows with Spring Integration using channels, routers, filters, splitters, aggregators, gateways, pollers, and protocol adapters.
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
Use this skill when building message-driven application flows with Spring Integration using channels, routers, filters, splitters, aggregators, gateways, pollers, and protocol adapters.
Use spring-integration for Enterprise Integration Patterns inside or at the edge of a Spring application.
spring-kafka, spring-amqp, or spring-pulsar when you only need direct broker APIs without an Integration flow.spring-cloud for distributed-system infrastructure such as Config, Gateway, or general service-to-service wiring.The ordinary Spring Integration job is:
| Situation | Use |
|---|---|
| One caller hands off to one handler inline | DirectChannel |
| The flow needs buffering between producer and consumer | QueueChannel |
| One message fans out to several subscribers | publish-subscribe channel |
| Application code sends into the flow | messaging gateway |
| External system sends one-way events | inbound adapter |
| External system expects request-reply behavior | inbound gateway |
Choose the simplest channel and endpoint pair that matches the delivery semantics. Add pollers only for sources that do not naturally push messages.
Use the Boot starter for core Integration features and add only the protocol modules the flow actually needs.
For the current stable line, Spring Integration is 7.0.4. The latest released Spring Boot line, 4.0.5, already manages Spring Integration 7.0.4. Older Boot 3.5.x applications still manage Spring Integration 6.5.8 and therefore remain a separate compatibility branch.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-file</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-http</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Remove any adapter or test module the flow does not actually use.
When Spring Boot already manages the module line, keep Spring Integration artifacts versionless. Add an exact version only on a standalone path that intentionally pins Spring Integration outside Boot-managed dependency control.
@MessagingGateway(defaultRequestChannel = "orders.input")
interface OrderGateway {
void submit(OrderCommand command);
}
@Bean
IntegrationFlow orderFlow(OrderValidator validator, OrderService service) {
return IntegrationFlow.from("orders.input")
.transform(OrderCommand.class, command -> command.normalize())
.filter(OrderCommand.class, validator::isValid)
.handle(service, "process")
.get();
}
This ordinary DSL chain covers the three most common endpoint types in one place: transformer, filter, and service activator.
@Bean
IntegrationFlow integrationErrors() {
return IntegrationFlow.from("errorChannel")
.handle(message -> logger.warn("integration failure", message.getPayload()))
.get();
}
Use the default errorChannel for the ordinary baseline. Open references/error-handling-and-retry-patterns.md when the flow needs endpoint advice, retry, circuit breaking, or explicit custom error-channel routing.
| Need | DSL shape |
|---|---|
| Change the payload | .transform(...) |
| Drop or reroute some messages | .filter(...) |
| Choose the next channel from content or headers | .route(...) |
| Invoke application code at the endpoint boundary | .handle(...) |
| Fan one message out into parts | .split(...) |
| Rejoin related messages | .aggregate(...) |
When a flow fans out and rejoins, define correlation, release, and timeout rules deliberately instead of assuming the default group behavior is correct for the business boundary.
@MessagingGateway(defaultRequestChannel = "orders.input")
interface OrderGateway {
void submit(OrderCommand command);
}
@Bean
IntegrationFlow orderFlow(OrderValidator validator, OrderService service) {
return IntegrationFlow.from("orders.input")
.transform(OrderCommand.class, command -> command.normalize())
.filter(OrderCommand.class, validator::isValid)
.handle(service, "process")
.get();
}
@ServiceActivator(inputChannel = "orders.validated")
void process(OrderCommand command) {
service.process(command);
}
Use this annotation shape only when the surrounding application already standardized on annotation-driven endpoint wiring. For new flows, keep the DSL-first handle(...) style as the default.
IntegrationFlow.from("orders.batches")
.split()
.channel("orders.parts")
.aggregate(aggregator -> aggregator
.correlationStrategy(message -> message.getHeaders().get("batchId"))
.releaseStrategy(group -> group.size() >= 10))
Pollers.fixedDelay(Duration.ofSeconds(5)).maxMessagesPerPoll(10)
.route(OrderCommand::priority, mapping -> mapping
.channelMapping(Priority.HIGH.name(), "orders.priority")
.channelMapping(Priority.NORMAL.name(), "orders.standard"))
Return these artifacts for the ordinary path:
source -> channel -> endpoint -> channel -> sink
orders.input
Pollers.fixedDelay(Duration.ofSeconds(5))
@SpringIntegrationTest, MockIntegrationContext, noAutoStartup, or graph-level assertions.