Skip to content
Kafka Is Fun

Getting Started · Beginner · Topic 3 of 5

Basic Producer with KafkaTemplate

KafkaTemplate is auto-configured: inject it. send() returns a CompletableFuture<SendResult>, and SendResult gives you the record metadata (partition and offset).

OrderProducer.javajava
@Service
@Slf4j
public class OrderProducer {

    private final KafkaTemplate<String, OrderEvent> kafkaTemplate;

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

    public void publishOrderCreated(Order order) {
        OrderEvent event = OrderEvent.builder()
            .orderId(order.getId())
            .status("CREATED")
            .timestamp(Instant.now())
            .build();

        kafkaTemplate.send("orders.order.created", order.getId(), event)
            .whenComplete((result, ex) -> {
                if (ex != null) {
                    log.error("Failed to publish order event: orderId={}", order.getId(), ex);
                } else {
                    log.info("Published order event: orderId={}, offset={}",
                        order.getId(), result.getRecordMetadata().offset());
                }
            });
    }

    // Synchronous send (blocks until the future completes)
    public void publishSync(String topic, String key, OrderEvent value) {
        try {
            SendResult<String, OrderEvent> result = kafkaTemplate.send(topic, key, value).get();
            log.info("Message sent to partition {} offset {}",
                result.getRecordMetadata().partition(),
                result.getRecordMetadata().offset());
        } catch (Exception e) {
            throw new RuntimeException("Failed to send message to Kafka", e);
        }
    }
}

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.