What dependencies and configuration are required to enable Spring Cloud Bus refresh in a service?
answer
- One starter: bus-amqp OR bus-kafka
- spring-boot-starter-actuator
- Broker props: rabbitmq.host / kafka bootstrap
- expose busrefresh via exposure.include
- still need @RefreshScope / @ConfigurationProperties
basics
~10 sAdd one broker starter — spring-cloud-starter-bus-amqp (RabbitMQ) or spring-cloud-starter-bus-kafka — plus Actuator, point the app at a running broker, and expose the endpoint with management.endpoints.web.exposure.include=busrefresh. Then POST /actuator/busrefresh.
solid answer
~30 sThree things. (1) Dependency: include exactly one Bus starter — spring-cloud-starter-bus-amqp for RabbitMQ or spring-cloud-starter-bus-kafka for Kafka; it pulls in Spring Cloud Stream and the binder. Also have spring-boot-starter-actuator. (2) Broker connectivity: standard properties like spring.rabbitmq.host/username/password or spring.kafka.bootstrap-servers so every instance connects to the same broker. (3) Expose the endpoint: management.endpoints.web.exposure.include=busrefresh (Actuator hides it by default). You also generally use it with spring-cloud-starter-config so instances actually have a Config Server to re-read from. With that in place, POST /actuator/busrefresh on any instance refreshes the cluster; add ?destination=app:** to scope it. Beans still need @RefreshScope or @ConfigurationProperties to pick up new values.
code
yaml · 19 lines# build.gradle
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-bus-kafka'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-starter-config'
}
# dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:${scVersion}" } }
# application.yml
spring:
kafka:
bootstrap-servers: kafka:9092
config:
import: "optional:configserver:http://config-server:8888"
management:
endpoints:
web:
exposure:
include: busrefresh, busenv, healthgo deeper
Know: add a broker starter + actuator and expose busrefresh.
List the two starters, the broker connection props, and the exposure.include requirement; note @RefreshScope still needed.
Add the Stream-binder/BOM alignment detail and busrefresh vs bus-refresh naming history.
Fold this into broker-selection and control-plane operability decisions.
**1. The starter.** Spring Cloud Bus ships as two convenience starters, differing only by broker: - **`spring-cloud-starter-bus-amqp`** → RabbitMQ (brings in the Rabbit Stream binder + spring-boot-starter-amqp). - **`spring-cloud-starter-bus-kafka`** → Apache Kafka (brings in the Kafka Stream binder). Include **exactly one**. Each transitively pulls in **Spring Cloud Stream**, which is the transport the Bus rides on. You also need **`spring-boot-starter-actuator`**, because `busrefresh` is an Actuator endpoint. In practice you also have **`spring-cloud-starter-config`** so the instance has a Config Server to re-fetch from on refresh (the Bus broadcasts the *signal*; the Config Server supplies the *values*). **2. Broker connectivity.** Every instance must reach the **same** broker so they share the `springCloudBus` destination: - RabbitMQ: `spring.rabbitmq.host`, `.port`, `.username`, `.password` (or a URI). - Kafka: `spring.kafka.bootstrap-servers` (and any binder/security props). If instances point at different brokers, refresh won't fan out. **3. Endpoint exposure.** Spring Boot Actuator exposes very few endpoints over HTTP by default. You must opt `busrefresh` in: ``` management.endpoints.web.exposure.include=busrefresh ``` (or a list including it, or `*` in non-prod). Forgetting this is the most common 'why is /actuator/busrefresh 404?' cause. In Spring Cloud 2.0+ the id is **`busrefresh`** (older docs say `bus-refresh`). The related property-push endpoint is **`busenv`**. **4. Verifying.** `POST http://any-instance:8080/actuator/busrefresh` (empty body). To scope: `?destination=<app>:**` or `?destination=<app>:<port>`, matched against each instance's `spring.cloud.bus.id`. **5. Don't forget @RefreshScope.** Wiring the Bus is necessary but not sufficient — a value only *changes* at runtime if it lives in a `@RefreshScope` bean or a `@ConfigurationProperties` class. Plain singletons keep startup values. **Optional knobs.** `spring.cloud.bus.enabled=false` to disable, `spring.cloud.bus.refresh.enabled`, `spring.cloud.bus.env.enabled`, `spring.cloud.bus.destination` to rename the shared topic, and `spring.cloud.bus.ack.enabled` / `trace.enabled` for acknowledgement/trace events. **Version management.** Use the Spring Cloud BOM (`spring-cloud-dependencies`) so the Bus, Stream, and binder versions align with your Boot version — mismatches are a frequent source of binder startup failures.
- Why does POST /actuator/busrefresh return 404 even though the Bus starter is on the classpath?Actuator does not expose the endpoint over HTTP by default. You must set management.endpoints.web.exposure.include to include busrefresh (or *). The bean exists but isn't web-exposed until then.
- Can you switch from RabbitMQ to Kafka without changing application code?Largely yes — swap spring-cloud-starter-bus-amqp for spring-cloud-starter-bus-kafka and change the broker connection properties. The Bus uses Spring Cloud Stream binders, so the RemoteApplicationEvent logic is broker-agnostic; only the binder and connection config differ.
saying these in an interview costs you the question
- Forgetting the exposure.include property and blaming the starter for a 404
- Including both bus-amqp and bus-kafka starters at once
- Thinking the Bus alone updates values without @RefreshScope/@ConfigurationProperties
- Assuming no broker is needed because 'it's just Spring'