Getting Started with Spring Boot
Add the KubeMQ starter, configure it, and run your first end-to-end publish-and-subscribe example in a Spring Boot app.
The KubeMQ Spring Boot starter brings auto-configuration, a KubeMQTemplate for sending, and annotation-driven listeners to any Spring Boot application. This guide walks you from an empty project to a running app that publishes and receives events end-to-end against a local broker.
Getting started
Prerequisites
You need the following installed:
| Requirement | Version |
|---|---|
| Java | 17+ |
| Spring Boot | 3.2.0+ |
| Docker | Any recent version (for a local broker) |
The starter talks to KubeMQ over gRPC only, so no HTTP connector or extra port is required for this guide.
Start KubeMQ
Run KubeMQ in Docker. The gRPC port 50000 is the only port the Spring Boot starter uses:
docker run -d \ --name kubemq \ -p 50000:50000 \ -e KUBEMQ_TOKEN=YOUR_LICENSE_KEY \ europe-docker.pkg.dev/kubemq/images/kubemq:nextThis matches the starter's default — KubeMQProperties.address is localhost:50000 out of the box, so a broker on the local machine needs no extra configuration.
Port 50000 is the native gRPC port used by all KubeMQ SDKs. The Spring Boot integration is built on the KubeMQ Java SDK, so it connects directly over gRPC rather than the shared HTTP server.
Add the Dependency
Add the starter to your build. It is published under the io.kubemq group, version 1.0.0.
dependencies {
implementation("io.kubemq:kubemq-spring-boot-starter:1.0.0")
}<dependency>
<groupId>io.kubemq</groupId>
<artifactId>kubemq-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>The starter is a dependency aggregator — adding it pulls in the auto-configuration module, the KubeMQTemplate, listener annotations, health, and metrics.
Configure application.yml
Configure the broker address and a client identifier under the kubemq prefix. Because this example is a non-web app, also set spring.main.web-application-type: none:
spring:
application:
name: kubemq-example-events-basic-pubsub
main:
web-application-type: none
kubemq:
address: ${KUBEMQ_ADDRESS:localhost:50000}
client-id: spring-events-basic-pubsubThe ${KUBEMQ_ADDRESS:localhost:50000} placeholder lets you override the broker address with an environment variable in other environments while defaulting to your local Docker broker. The client-id is sent with every request and identifies this application to the broker.
Send a Message
Inject KubeMQTemplate into any Spring bean and call sendEvent(channel, payload). The template serializes the payload and publishes a fire-and-forget event:
import io.kubemq.spring.boot.autoconfigure.template.KubeMQTemplate;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
private final KubeMQTemplate template;
public OrderService(KubeMQTemplate template) {
this.template = template;
}
public void placeOrder(Order order) {
template.sendEvent("orders", order);
}
}sendEvent is overloaded — you can pass a Map<String, String> of tags as a third argument, and sendEventAsync returns a CompletableFuture<Void> for non-blocking sends.
Receive a Message
Annotate a method with @KubeMQEventListener to subscribe to one or more channels. The method receives an EventMessageReceived; call getBody() to read the raw payload bytes:
package io.kubemq.spring.boot.examples.events;
import io.kubemq.sdk.pubsub.EventMessageReceived;
import io.kubemq.spring.boot.autoconfigure.listener.KubeMQEventListener;
import java.nio.charset.StandardCharsets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class BasicPubSubListener {
private static final Logger log = LoggerFactory.getLogger(BasicPubSubListener.class);
@KubeMQEventListener(channels = "spring-events.basic-pubsub")
public void onEvent(EventMessageReceived event) {
byte[] body = event.getBody();
String text = body != null ? new String(body, StandardCharsets.UTF_8) : "<empty>";
log.info("Received event: channel={} body={}", event.getChannel(), text);
}
}The channels attribute accepts one or more channel names and supports SpEL expressions and property placeholders (for example channels = "${kubemq.channels.orders}").
Run and Observe
Start your application. The listener subscribes on startup, the publisher sends three events to spring-events.basic-pubsub, and both sides log to the console. You should see interleaved Published and Received lines:
INFO Received event: channel=spring-events.basic-pubsub body=Hello KubeMQ #1
INFO Published event to spring-events.basic-pubsub: Hello KubeMQ #1
INFO Received event: channel=spring-events.basic-pubsub body=Hello KubeMQ #2
INFO Published event to spring-events.basic-pubsub: Hello KubeMQ #2
INFO Received event: channel=spring-events.basic-pubsub body=Hello KubeMQ #3
INFO Published event to spring-events.basic-pubsub: Hello KubeMQ #3
INFO Basic pub/sub example completed.Events are fire-and-forget: the listener must be subscribed before a message is sent, otherwise that message is not delivered. The example inserts a short warm-up delay before publishing so the subscription is established first.
Java vs Kotlin
The starter is fully usable from Java with YAML configuration. The optional kubemq-spring-boot-starter-kotlin module adds a configuration DSL and coroutine-friendly suspend extensions.
Configure with application.yml and send with the blocking sendEvent:
@Service
public class OrderService {
private final KubeMQTemplate template;
public OrderService(KubeMQTemplate template) {
this.template = template;
}
public void placeOrder(Order order) {
template.sendEvent("orders", order);
}
}Configure programmatically with the kubemq { } DSL by exposing it as a bean:
import io.kubemq.spring.boot.kotlin.KubeMQConfigurerDsl
import io.kubemq.spring.boot.kotlin.kubemq
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration
class KubeMQConfig {
@Bean
fun kubemqConfigurer(): KubeMQConfigurerDsl = kubemq {
address = "localhost:50000"
clientId = "spring-kotlin-dsl-config"
}
}Send from a coroutine with the sendEventSuspend extension, which suspends until the underlying async send completes:
import io.kubemq.spring.boot.autoconfigure.template.KubeMQTemplate
import io.kubemq.spring.boot.kotlin.sendEventSuspend
import kotlinx.coroutines.runBlocking
import org.springframework.boot.ApplicationArguments
import org.springframework.boot.ApplicationRunner
import org.springframework.stereotype.Component
@Component
class CoroutinePublishRunner(private val template: KubeMQTemplate) : ApplicationRunner {
override fun run(args: ApplicationArguments) {
runBlocking {
template.sendEventSuspend("spring-kotlin.coroutine-publish", "Coroutine event")
}
}
}Was this page helpful?
Spring Boot Concepts
Understand the auto-configuration model, KubeMQTemplate, annotation-driven listeners, and how the integration's modules fit together.
Commands & Queries
Synchronous request-response (RPC) messaging using KubeMQTemplate and the @KubeMQCommandHandler / @KubeMQQueryHandler annotations.