How do you enable Kafka Streams in a Spring (Boot) application, and what does @EnableKafkaStreams actually wire up?
answer
- @EnableKafkaStreams on @Configuration
- bean name defaultKafkaStreamsConfig
- KafkaStreamsConfiguration wraps StreamsConfig
- app.id + bootstrap.servers required
- Boot: spring.kafka.streams.* still needs the annotation
basics
~10 sPut @EnableKafkaStreams on a @Configuration class and provide a KafkaStreamsConfiguration bean named defaultKafkaStreamsConfig that sets the application.id and bootstrap.servers. Spring then creates a StreamsBuilderFactoryBean that builds and starts Kafka Streams.
solid answer
~30 sKafka Streams is Kafka's client library for processing streams. In Spring you turn it on with @EnableKafkaStreams on a @Configuration class. That annotation looks for one KafkaStreamsConfiguration bean whose name equals the constant KafkaStreamsDefaultConfiguration.DEFAULT_STREAMS_CONFIG_BEAN_NAME ("defaultKafkaStreamsConfig"); it must carry at least APPLICATION_ID_CONFIG and BOOTSTRAP_SERVERS_CONFIG. With those in place Spring registers a StreamsBuilderFactoryBean named "defaultKafkaStreamsBuilder" that exposes a StreamsBuilder and manages the KafkaStreams lifecycle. In Spring Boot you can instead set spring.kafka.streams.* properties (application-id, bootstrap-servers) and Boot builds the KafkaStreamsConfiguration for you — but you still add @EnableKafkaStreams to activate it. You then define topology beans that take a StreamsBuilder parameter.
code
java · 22 linesimport org.apache.kafka.streams.StreamsConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.EnableKafkaStreams;
import org.springframework.kafka.annotation.KafkaStreamsDefaultConfiguration;
import org.springframework.kafka.config.KafkaStreamsConfiguration;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableKafkaStreams
public class StreamsConfigJava {
@Bean(name = KafkaStreamsDefaultConfiguration.DEFAULT_STREAMS_CONFIG_BEAN_NAME)
public KafkaStreamsConfiguration kStreamsConfig() {
Map<String, Object> props = new HashMap<>();
props.put(StreamsConfig.APPLICATION_ID_CONFIG, "orders-streams");
props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
return new KafkaStreamsConfiguration(props);
}
}go deeper
Know the annotation, the required named config bean, and app.id/bootstrap.servers.
Explain KafkaStreamsConfiguration wrapping StreamsConfig and the Boot property shortcut still needing the annotation.
Discuss the two reserved bean names and how the default StreamsBuilderFactoryBean is derived.
Reason about multi-topology setups, unique application.id semantics, and when Streams beats @KafkaListener.
**What Kafka Streams is (just enough).** Kafka Streams is a Java client library that reads records from Kafka topics, transforms/aggregates them, and writes results back to Kafka. Spring for Apache Kafka doesn't reimplement it — it *wires it into the Spring context* so you get dependency injection, bean lifecycle (start/stop), and configuration from properties. **The activation annotation — `@EnableKafkaStreams`.** You place it on a `@Configuration` class (commonly the same one that has `@EnableKafka`). Under the hood it `@Import`s `KafkaStreamsDefaultConfiguration`. That configuration does two things: 1. It **requires** a bean of type `org.springframework.kafka.config.KafkaStreamsConfiguration` **named exactly** `defaultKafkaStreamsConfig` — the constant `KafkaStreamsDefaultConfiguration.DEFAULT_STREAMS_CONFIG_BEAN_NAME`. If that bean is missing you get a startup failure. This bean wraps a `Map<String,Object>` of Kafka `StreamsConfig` properties; at minimum `StreamsConfig.APPLICATION_ID_CONFIG` (the consumer-group / app identity) and `StreamsConfig.BOOTSTRAP_SERVERS_CONFIG` (broker list). 2. It **registers** a `StreamsBuilderFactoryBean` named `defaultKafkaStreamsBuilder` (constant `DEFAULT_STREAMS_BUILDER_BEAN_NAME`), built from that config. This factory bean produces the `StreamsBuilder` you inject into topology beans and owns the resulting `KafkaStreams` instance. **`KafkaStreamsConfiguration` vs raw `StreamsConfig`.** `StreamsConfig` is the Kafka-library config object. `KafkaStreamsConfiguration` is Spring's thin wrapper (`asProperties()`) so the config can live as a Spring bean and be assembled from typed values. You populate it with the same `StreamsConfig.*` keys you'd use natively (e.g. `DEFAULT_KEY_SERDE_CLASS_CONFIG`, `NUM_STREAM_THREADS_CONFIG`). **The Spring Boot shortcut.** If `spring-kafka` is on the classpath, Boot's `KafkaStreamsAnnotationDrivenConfiguration` kicks in *only when* `@EnableKafkaStreams` is present. Boot then synthesizes the `defaultKafkaStreamsConfig` bean from `spring.kafka.streams.application-id`, `spring.kafka.streams.bootstrap-servers` (falling back to `spring.kafka.bootstrap-servers`), and other `spring.kafka.streams.*` properties. Common gotcha: forgetting `@EnableKafkaStreams` — Boot will *not* auto-start streams without it, and setting only the properties does nothing. **Minimal wiring example.** A `@Configuration` + `@EnableKafkaStreams`, a `@Bean(name = KafkaStreamsDefaultConfiguration.DEFAULT_STREAMS_CONFIG_BEAN_NAME)` returning `KafkaStreamsConfiguration`, and a topology `@Bean(StreamsBuilder)`. **When to use.** Reach for Kafka Streams (over `@KafkaListener`) when you need stateful transformations, joins, windowed aggregations, or exactly-once processing across topics — not for simple consume-and-handle. **Gotchas.** (1) The config bean name must match the constant exactly or you get an unsatisfied-dependency error. (2) `application.id` must be unique per logical app; it drives the consumer group and internal changelog/repartition topic names. (3) You get exactly one default `StreamsBuilderFactoryBean`; running two distinct topologies with different `application.id`s needs additional explicitly-named factory beans.
- What happens if you set spring.kafka.streams.application-id but forget @EnableKafkaStreams?Nothing starts. Boot's streams auto-configuration is gated on the annotation, so no StreamsBuilderFactoryBean is created and no KafkaStreams instance runs.
- Why must the config bean be named exactly 'defaultKafkaStreamsConfig'?KafkaStreamsDefaultConfiguration looks it up by that reserved name (the DEFAULT_STREAMS_CONFIG_BEAN_NAME constant) to build the default StreamsBuilderFactoryBean; any other name leaves the dependency unsatisfied.
saying these in an interview costs you the question
- Thinking @EnableKafkaStreams alone is enough without providing a KafkaStreamsConfiguration bean
- Claiming Spring reimplements the Kafka Streams DSL (it only wires the library)
- Believing setting spring.kafka.streams.* properties auto-starts streams without the annotation