Explain what /actuator/beans, /actuator/mappings, and /actuator/conditions each expose and when you'd reach for them.
answer
- beans = graph: name/type/scope/dependencies
- mappings = URL+method -> handler
- conditions = auto-config positive/negative matches + reasons
- conditions == old 'autoconfig' == --debug report
- internal structure -> keep out of open prod
basics
~20 s/beans lists every Spring bean with its type, scope and dependencies. /mappings lists all request mappings (which URL/method routes to which handler). /conditions shows the auto-configuration report: which @Conditional auto-configs matched (were applied) and which didn't, with reasons.
solid answer
~40 sThese three are context-introspection endpoints for debugging how the application assembled itself. `/actuator/beans` (`BeansEndpoint`) dumps the `ApplicationContext` bean graph per context: each bean's name, fully-qualified type, scope (`singleton`/`prototype`), and its `dependencies`. `/actuator/mappings` (`MappingsEndpoint`) lists all web mappings — for Spring MVC the `DispatcherServlet` `@RequestMapping` handlers (path patterns, methods, produces/consumes, the handler method) plus servlet/filter mappings; for WebFlux the `DispatcherHandler` routes. `/actuator/conditions` (`ConditionsReportEndpoint`, historically named `autoconfig`) reports the auto-configuration decision log: `positiveMatches` (conditions that passed, so the bean/config was created), `negativeMatches` (conditions that failed, with the specific reason like 'missing bean' or 'property not set'), plus unconditional classes and exclusions. You reach for `/conditions` when auto-config didn't wire what you expected, `/mappings` when a route 404s or collides, and `/beans` when you suspect a duplicate/missing/wrong-typed bean.
code
java · 26 lines// /actuator/conditions (excerpt) — WHY a bean was or wasn't auto-configured
{
"contexts": { "application": {
"positiveMatches": {
"DataSourceAutoConfiguration#dataSource": [
{ "condition": "OnClassCondition", "message": "@ConditionalOnClass found DataSource" }
]
},
"negativeMatches": {
"RedisAutoConfiguration": {
"notMatched": [
{ "condition": "OnClassCondition",
"message": "@ConditionalOnClass did not find RedisOperations" }
], "matched": [] }
}
} }
}
// /actuator/mappings (excerpt) — which route hits which handler method
{
"contexts": { "application": { "mappings": { "dispatcherServlets": {
"dispatcherServlet": [ {
"handler": "com.acme.OrderController#get(Long)",
"predicate": "{ GET [/orders/{id}], produces [application/json] }"
} ] } } } }
}go deeper
Know beans=bean list, mappings=routes, conditions=what auto-config matched.
Explain the concrete fields (scope/type/dependencies; predicate/handler; positive/negative matches with reasons) and which to use per symptom.
Tie conditions to @Conditional evaluation and @ConditionalOnMissingBean back-off; note the autoconfig→conditions rename.
Weigh the reconnaissance risk of exposing structure and standardize which introspection endpoints are allowed per environment.
All three answer 'why did my Spring context end up like this?' — they are read-only introspection endpoints, invaluable for debugging misconfiguration without a debugger. **`/actuator/beans` — `BeansEndpoint`.** Returns, per `ApplicationContext` (there can be a parent + child, e.g. management context), a `beans` map. Each entry: ```json "orderService": { "aliases": [], "scope": "singleton", "type": "com.acme.OrderService", "resource": "file [.../OrderService.class]", "dependencies": [ "orderRepository", "meterRegistry" ] } ``` So you get the bean name (map key), any `aliases`, the **scope** (`singleton`, `prototype`, or a web scope), the concrete **type**, the defining **resource**, and the **dependencies** (other bean names injected). Use it to spot: a bean that exists twice under different names, a bean of the wrong concrete type (e.g. a CGLIB proxy), or a dependency that isn't what you assumed. **`/actuator/mappings` — `MappingsEndpoint`.** Enumerates request-to-handler wiring. For a servlet (MVC) app it reports: - **`dispatcherServlets`**: each `@RequestMapping`/`@GetMapping` etc. with its `predicate` (path pattern, HTTP methods, `params`, `headers`, `produces`, `consumes`) and the target **handler method**. - **`servletFilters`** and **`servlets`**: filter and servlet registrations with their URL patterns. For WebFlux it reports `dispatcherHandlers` including functional `RouterFunction` routes. This is the go-to when a URL returns 404 (no mapping / wrong pattern), 405 (method mismatch), or two handlers ambiguously match the same path. **`/actuator/conditions` — `ConditionsReportEndpoint`.** This is the **auto-configuration condition evaluation report** (the same information you get from launching with `--debug`). Spring Boot's auto-configurations are guarded by `@Conditional` annotations (`@ConditionalOnClass`, `@ConditionalOnMissingBean`, `@ConditionalOnProperty`, etc.). The report groups, per context: - **`positiveMatches`**: auto-config classes/methods whose conditions **passed**, so their beans were created — each with the condition and the message ('matched'). - **`negativeMatches`**: those whose conditions **failed** — each with *why* (e.g. `@ConditionalOnMissingBean` did not match because a bean of that type was already present, or `@ConditionalOnProperty` didn't match because the property was absent/false). - **`unconditionalClasses`**: always-applied configs. - **`exclusions`**: auto-configs you explicitly excluded. This is the single most useful endpoint for 'why is X not auto-configured?' or 'why did Spring back off from my custom bean?'. **Cross-cutting gotchas.** - These endpoints expose your **internal structure** (class names, dependency wiring, routes) — sensitive reconnaissance data. They must not be openly web-exposed in production; keep them behind auth or unexposed. (Exposure config itself is the Boot-config leaf, but the sensitivity is a property of these endpoints.) - **Not web-exposed by default** — expect 404 until exposed. - `/beans` and `/conditions` show a *snapshot at startup* of the (immutable) context — they don't change at runtime. - `conditions` was renamed from `autoconfig` in Boot 2.0; older docs/answers using `autoconfig` are stale. - `/mappings` shows the *effective* mappings after all customizers/interceptors register — great for catching path-prefix or context-path surprises. **When to use which.** Route problem → `mappings`. 'Spring didn't create/overrode my bean' → `conditions`. 'Which bean/what type/what deps' → `beans`.
- Your custom @Bean of a type Spring also auto-configures seems ignored. Which endpoint pinpoints why, and what would you look for?/actuator/conditions. Look under negativeMatches for the relevant auto-configuration reporting a @ConditionalOnMissingBean that 'did not match because a bean was already present' — confirming Spring backed off in favor of your bean (or, if it's under positiveMatches, that the auto-config bean won).
- Why should these three endpoints not be openly exposed in production?They reveal internal architecture — all bean types and wiring, every route and its handler, and the full auto-config decision tree. That's valuable reconnaissance for an attacker, so they should stay unexposed or behind authentication.
saying these in an interview costs you the question
- Confusing /mappings (routes) with /beans (bean graph)
- Calling the conditions endpoint 'autoconfig' as if that's the current id
- Thinking these endpoints are safe to expose publicly
- Believing /beans reflects live runtime mutation rather than the startup context