Spring Boot 4 Actuator in production: endpoints, security, custom health indicators

Companion repository for the ankurm.com article. Every transcript in docs/output/
was produced by running this project; scripts/run-all.sh regenerates all of them.

Verified against Spring Boot 4.1.1 / Framework 7.0.9 / Security 7.1.1 /
Micrometer 1.17.1 / kafka-clients 4.2.1 on Temurin JDK 25.0.4.1+1.
This commit is contained in:
2026-09-04 10:40:04 +05:30
commit 4b6cefa60a
64 changed files with 3195 additions and 0 deletions

107
docs/02-boot-4-changes.md Normal file
View File

@@ -0,0 +1,107 @@
[← 01 What Actuator exposes](01-what-actuator-exposes.md) · **02 · What changed in Spring Boot 4** · [03 The endpoint catalogue →](03-endpoint-catalogue.md)
# 02 — What changed in Spring Boot 4
Every claim below was checked against the 4.1.1 jars with `javap`, or against the 3.5.16 jars
for the "before" side. None of it came from a migration blog.
## `HealthIndicator` moved module and package
This is the one that breaks every custom health indicator ever written.
```
Boot 3.5.16 org.springframework.boot.actuate.health.HealthIndicator (spring-boot-actuator)
Boot 4.1.1 org.springframework.boot.health.contributor.HealthIndicator (spring-boot-health)
```
`org.springframework.boot.actuate.health` does not exist in Boot 4.1.1 at all — not deprecated,
absent. `Health`, `Status`, `AbstractHealthIndicator`, `HealthContributor` and the composites
all moved with it, into a new `spring-boot-health` module.
Two neighbouring packages in the same new module are worth knowing:
- `org.springframework.boot.health.application``DiskSpaceHealthIndicator`,
`LivenessStateHealthIndicator`, `ReadinessStateHealthIndicator`, `SslHealthIndicator`
- `org.springframework.boot.health.registry``HealthContributorRegistry`, which is how
[`DiagnosticsEndpoint`](../src/main/java/com/ankurm/actuator/web/DiagnosticsEndpoint.java)
enumerates contributors at runtime
## The interface method was renamed
```java
// Boot 3.5.16
public interface HealthIndicator extends HealthContributor {
default Health getHealth(boolean includeDetails);
Health health();
}
// Boot 4.1.1
public interface HealthIndicator extends HealthContributor {
default Health health(boolean includeDetails);
Health health();
}
```
If you overrode `getHealth(boolean)` — which people do to control detail rendering — it now
silently stops being an override. Add `@Override` and let the compiler find it.
`Health` also stopped extending `HealthComponent`; that class is gone from Boot 4.1.1 entirely.
## `EndpointRequest` moved too
```
Boot 3.5.16 org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest
Boot 4.1.1 org.springframework.boot.security.autoconfigure.actuate.web.servlet.EndpointRequest
```
Same class, same static methods (`toAnyEndpoint()`, `to(Class...)`, `to(String...)`,
`toLinks()`, `toAdditionalPaths(...)`), new package, and it now ships in `spring-boot-security`
rather than `spring-boot-actuator-autoconfigure`. The reactive variant made the equivalent move.
## `RestClient` is not in the web starter any more
Boot 4 split the framework into fine-grained modules, and `RestClient` auto-configuration went
with it. Adding `spring-boot-starter-webmvc` and injecting `RestClient.Builder` fails at
startup:
```
Parameter 0 of constructor in com.ankurm.actuator.health.ExternalApiHealthIndicator
required a bean of type 'org.springframework.web.client.RestClient$Builder' that could not be found.
```
The fix is one dependency:
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-restclient</artifactId>
</dependency>
```
This cost a startup cycle while building this repository, which is why it is documented here
rather than glossed over.
## Liveness and readiness probes are on by default
From the 4.0 migration guide, and confirmed by running the app with no configuration at all —
`/actuator/health` reports `"groups":["liveness","readiness"]` out of the box. Turn them off
with `management.endpoint.health.probes.enabled=false` if you genuinely do not want them.
## Nullability annotations
Actuator endpoint parameters can no longer use `org.springframework.lang.Nullable` to mark a
parameter optional. Migrate to `org.jspecify.annotations.Nullable`.
## There is no Micrometer 2
Several migration write-ups claim Boot 4 replaces "legacy Actuator endpoints" with a
"Micrometer 2 observability stack". Spring Boot 4.1.1 resolves **Micrometer 1.17.1**
(`docs/output/00-versions.txt`), and `maven-metadata.xml` for `micrometer-core` shows 1.17.1 as
the newest GA with 1.18.0-M1 as a milestone. Metrics *did* move to their own module
(`spring-boot-micrometer-metrics`, which `spring-boot-starter-actuator` still pulls in), and
there is a new `spring-boot-starter-opentelemetry`. Neither of those is a major Micrometer
release.
---
[← 01](01-what-actuator-exposes.md) · **02** · [03 The endpoint catalogue →](03-endpoint-catalogue.md)