skip to content

Explain what /actuator/beans, /actuator/mappings, and /actuator/conditions each expose and when you'd reach for them.

level: middleimportance: should knowfreq 35%

answer

  1. beans = graph: name/type/scope/dependencies
  2. mappings = URL+method -> handler
  3. conditions = auto-config positive/negative matches + reasons
  4. conditions == old 'autoconfig' == --debug report
  5. 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 s

These 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
java
// /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

for a junior

Know beans=bean list, mappings=routes, conditions=what auto-config matched.

for a middle

Explain the concrete fields (scope/type/dependencies; predicate/handler; positive/negative matches with reasons) and which to use per symptom.

for a senior

Tie conditions to @Conditional evaluation and @ConditionalOnMissingBean back-off; note the autoconfig→conditions rename.

for a principal

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

context