At what point in the SpringApplication lifecycle do FailureAnalyzers run, and why does that timing dictate how you get dependencies into them?
answer
- runs in SpringApplication failure path, post-refresh
- FailureAnalyzers = a SpringBootExceptionReporter
- context already dead -> no @Autowired
- only BeanFactoryAware / EnvironmentAware injection
- original exception rethrown -> non-zero exit
basics
~10 sThey 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 sFailureAnalyzers 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
Know it happens only when startup fails, not at runtime.
Know the context is already broken, so no autowiring.
Trace it to SpringApplication's failure path via SpringBootExceptionReporter/FailureAnalyzers and the aware-interface injection.
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