skip to content

At what point in the SpringApplication lifecycle do FailureAnalyzers run, and why does that timing dictate how you get dependencies into them?

level: seniorimportance: nice to knowfreq 15%

answer

  1. runs in SpringApplication failure path, post-refresh
  2. FailureAnalyzers = a SpringBootExceptionReporter
  3. context already dead -> no @Autowired
  4. only BeanFactoryAware / EnvironmentAware injection
  5. original exception rethrown -> non-zero exit

basics

~10 s

They run after startup has already failed — when SpringApplication catches the fatal exception and reports it, before rethrowing. Because the context is dead, you can't autowire beans; you use EnvironmentAware/BeanFactoryAware injection instead.

solid answer

~40 s

FailureAnalyzers are invoked by `SpringApplication` in its failure-reporting path: when `run()` throws during context refresh or web-server start, Boot's exception handling (via `SpringBootExceptionReporter` / the `FailureAnalyzers` reporter) loops through registered analyzers to find one that explains the exception, reports it through `LoggingFailureAnalysisReporter`, and then rethrows so the JVM still exits non-zero. Critically, this happens *after* the application context has failed, so there is no fully-initialized context and no dependency injection. That's why analyzers are loaded via `SpringFactoriesLoader` rather than as beans, and why the only supported way to pull in collaborators is to implement `BeanFactoryAware` or `EnvironmentAware` — Boot passes in the (partially built) bean factory and the environment when it constructs the analyzers.

go deeper

for a junior

Know it happens only when startup fails, not at runtime.

for a middle

Know the context is already broken, so no autowiring.

for a senior

Trace it to SpringApplication's failure path via SpringBootExceptionReporter/FailureAnalyzers and the aware-interface injection.

for a principal

Reason about defensive access to a partial BeanFactory and keeping analyzers cheap and side-effect-free on the failure path.

## Where in the lifecycle Roughly, `SpringApplication.run()` does: create the `ApplicationContext`, `prepareContext`, then `refreshContext` (bean creation, web server start). If any of that throws, `run()` catches it and calls its private `handleRunFailure` path, which: 1. Fires `ApplicationFailedEvent`. 2. Runs the registered `SpringBootExceptionReporter`s — the important one is `FailureAnalyzers`, which holds the list of `FailureAnalyzer`s. 3. `FailureAnalyzers.reportException` walks the analyzers; the first non-null `FailureAnalysis` is handed to a `FailureAnalysisReporter` (default `LoggingFailureAnalysisReporter`) to print the banner. 4. The original exception is **rethrown**, so the process still terminates with a failure exit code. ## Why the context is unusable By the time an analyzer runs, refresh has failed — beans may be half-created or absent, and the context is effectively dead. So: - You **cannot** `@Autowired` into an analyzer. - Analyzers are **not** beans; Boot instantiates them itself from `spring.factories` via `SpringFactoriesLoader`, using a no-arg constructor. ## Supported injection: the aware interfaces When `FailureAnalyzers` constructs the analyzers, it checks whether each one implements `BeanFactoryAware` or `EnvironmentAware` and, if so, calls the setter with the context's `ConfigurableListableBeanFactory` / `ConfigurableEnvironment`. This gives you read access to configuration (e.g. to look up which `server.port` was requested, or to name a property in the Action). These are the **only** two supported injections. ## Consequences / gotchas - **Don't do heavy work in an analyzer's constructor** — it's created during a failure path; keep it cheap and side-effect-free. - **The bean factory may be partial** — treat `BeanFactoryAware` access defensively; a bean you want may not exist because that's *why* startup failed. - **It runs once, on the fatal exception** — not for every intermediate exception that Spring internally recovers from. - **Runtime exceptions after startup are out of scope** — this is a startup-diagnostics feature only. ## When this matters in interviews Candidates who understand this timing can explain *why* the registration mechanism is `spring.factories` and *why* DI doesn't work — connecting the packaging rule to the lifecycle constraint rather than memorizing it.

  • Does reporting a FailureAnalysis stop the JVM from exiting with an error?
    No. After the banner is printed, SpringApplication rethrows the original exception, so the process still exits non-zero. The analysis only improves the message; it does not swallow the failure.

saying these in an interview costs you the question

  • Thinking reporting an analysis prevents the app from exiting with an error
  • Believing FailureAnalyzers handle runtime request exceptions
  • Assuming the bean factory passed via BeanFactoryAware is fully populated

context