skip to content

What is KafkaTemplate and how do you use it to send a message to a Kafka topic in Spring?

level: juniorimportance: must knowfreq 78%

answer

  1. thin wrapper over native KafkaProducer
  2. needs a ProducerFactory
  3. send(topic, key, value) -> CompletableFuture<SendResult>
  4. Boot auto-configures from spring.kafka.*
  5. thread-safe singleton

basics

~10 s

KafkaTemplate is Spring's helper for producing messages. You inject it and call template.send("topic", key, value). Spring Boot auto-configures it from application.properties, so you just autowire and send.

solid answer

~30 s

KafkaTemplate<K,V> is Spring for Apache Kafka's central producer abstraction — a thin, thread-safe wrapper over the native Kafka Producer. Spring Boot auto-configures a bean when spring-kafka is on the classpath and spring.kafka.* properties are set, wiring in a ProducerFactory. You inject it and call send(topic, value), send(topic, key, value), or send(ProducerRecord). It serializes the key/value with the configured serializers, hands the record to the underlying producer's send, and returns a CompletableFuture<SendResult<K,V>> for the async result. You can also set a defaultTopic. It centralizes producer config (bootstrap servers, serializers, acks) so business code just calls send.

code

java · 21 lines
java
@Service
public class OrderProducer {
    private final KafkaTemplate<String, String> kafkaTemplate;

    public OrderProducer(KafkaTemplate<String, String> kafkaTemplate) {
        this.kafkaTemplate = kafkaTemplate;
    }

    public void publish(String orderId, String payload) {
        // key = orderId ensures per-order ordering on one partition
        kafkaTemplate.send("orders", orderId, payload);
    }
}

// application.yml
// spring:
//   kafka:
//     bootstrap-servers: localhost:9092
//     producer:
//       key-serializer: org.apache.kafka.common.serialization.StringSerializer
//       value-serializer: org.apache.kafka.common.serialization.StringSerializer

go deeper

for a junior

Know it's the Spring class for sending, that you inject it and call send(topic, key, value), and that Boot auto-configures it.

for a middle

Explain the ProducerFactory relationship, the send overloads, and that it returns a future.

for a senior

Discuss thread-safety, serializer wiring, defaultTopic, and that failures surface via the future not an exception.

for a principal

Frame it as a thin managed wrapper; reason about shared-producer semantics, config centralization, and where transactions/idempotence plug in via the factory.

**KafkaTemplate** (`org.springframework.kafka.core.KafkaTemplate<K,V>`) is the producer-side entry point of the *Spring for Apache Kafka* project. Kafka's own client library gives you a low-level `org.apache.kafka.clients.producer.KafkaProducer` that you must construct, configure, and close yourself. KafkaTemplate wraps that producer and gives it a Spring flavor: it's a managed bean, it's thread-safe, and it removes boilerplate. **How it gets created.** KafkaTemplate needs a `ProducerFactory<K,V>`, which knows how to create the underlying Kafka `Producer` (bootstrap servers, key/value serializers, acks, etc.). With Spring Boot, adding the `spring-kafka` dependency and setting `spring.kafka.bootstrap-servers`, `spring.kafka.producer.key-serializer`, and `spring.kafka.producer.value-serializer` in `application.yml` triggers auto-configuration that creates both a `DefaultKafkaProducerFactory` and a `KafkaTemplate` bean for you. Without Boot you declare these `@Bean`s yourself. **Sending.** The core overloads are: - `send(String topic, V data)` — value only; key is null. - `send(String topic, K key, V data)` — key + value (key drives partitioning). - `send(String topic, Integer partition, K key, V data)` — explicit partition. - `send(ProducerRecord<K,V> record)` — full control including headers and timestamp. - `sendDefault(...)` — uses the `defaultTopic` configured on the template. Every `send` is **asynchronous**: it returns a `CompletableFuture<SendResult<K,V>>` that completes when the broker acknowledges (or fails). The record is placed into the producer's in-memory batch buffer and flushed by a background I/O thread. **Terms defined.** - *Serializer*: converts your K/V objects to `byte[]` for the wire (e.g. `StringSerializer`, `JsonSerializer`). - *ProducerRecord*: the unit sent to Kafka — topic, optional partition, optional key, value, headers, timestamp. - *SendResult*: what you get back on success — the original `ProducerRecord` plus `RecordMetadata` (topic, partition, offset, timestamp) assigned by the broker. **When to use.** Any time application code needs to publish to Kafka. It's the standard, and you almost never touch the raw `KafkaProducer`. **Gotchas.** (1) send() does *not* throw on delivery failure synchronously — you must handle the returned future or you'll silently lose errors. (2) The template is thread-safe and meant to be a singleton — don't create one per request. (3) It only *produces*; consuming is a separate concern (`@KafkaListener` / `KafkaTemplate` is not for reading).

  • Does send() block until the broker acknowledges the message?
    No. send() is asynchronous — it buffers the record and returns a CompletableFuture<SendResult> immediately. It completes later on the producer I/O thread. To block you'd call .get() on the future (with the risk of blocking the caller).
  • Where does KafkaTemplate get its configuration from?
    From its ProducerFactory (usually DefaultKafkaProducerFactory), which holds the producer config map — bootstrap servers, serializers, acks, etc. Spring Boot builds it from spring.kafka.producer.* properties.

saying these in an interview costs you the question

  • Thinking send() blocks until acknowledged / is synchronous by default
  • Creating a new KafkaTemplate per request instead of reusing the singleton bean
  • Believing KafkaTemplate is also used for consuming messages
  • Assuming a delivery error is thrown from send() rather than surfaced via the returned future

context