Skip to content
Kafka Is Fun

Advanced Patterns · Advanced · Topic 2 of 5

Kafka Streams with Spring Boot

Declare @EnableKafkaStreams and Spring Boot builds the Streams configuration from the spring.kafka.streams properties; a StreamsBuilder is available to inject. Kafka's own Streams settings go under spring.kafka.streams.properties, where dotted keys are written in brackets.

OrderStreamProcessor.javajava
@Configuration
@EnableKafkaStreams
@Slf4j
public class OrderStreamProcessor {

    @Bean
    public KStream<String, OrderEvent> orderPipeline(StreamsBuilder streamsBuilder) {

        // Spring Kafka 4.x name; earlier versions call it JsonSerde
        var orderSerde = new JacksonJsonSerde<>(OrderEvent.class);

        KStream<String, OrderEvent> orders = streamsBuilder
            .stream("orders.order.created",
                Consumed.with(Serdes.String(), orderSerde));

        // Filter + transform + route
        orders
            .filter((key, event) -> event.getAmount() > 1000)
            .mapValues(event -> EnrichedOrder.from(event, lookupService.getCustomer(event.getCustomerId())))
            .to("orders.high-value", Produced.with(Serdes.String(), new JacksonJsonSerde<>(EnrichedOrder.class)));

        // Aggregate: count orders per customer in 1-hour tumbling windows, no grace period
        orders
            .groupByKey()
            .windowedBy(TimeWindows.ofSizeWithNoGrace(Duration.ofHours(1)))
            .count()
            .toStream()
            .map((windowedKey, count) ->
                KeyValue.pair(windowedKey.key(), new OrderCount(windowedKey.key(), count)))
            .to("analytics.order-counts", Produced.with(Serdes.String(), new JacksonJsonSerde<>(OrderCount.class)));

        return orders;
    }
}
application.yml (Streams config)yaml
spring:
  kafka:
    streams:
      application-id: order-stream-processor
      bootstrap-servers: localhost:9092
      state-dir: /var/lib/kafka-streams
      properties:
        "[default.key.serde]": org.apache.kafka.common.serialization.Serdes$StringSerde
        "[processing.guarantee]": exactly_once_v2
        "[num.stream.threads]": 4
        "[statestore.cache.max.bytes]": 10485760   # 10 MB; replaces the deprecated cache.max.bytes.buffering

Sources

Checked against Spring for Apache Kafka 4.1.1, Spring Boot 4.1.1 and Kafka 4.2 documentation on 11 October 2026. Draft: not yet reviewed by a Kafka specialist, and releases move on, so confirm against the current documentation before you act on it.