spring-projects / spring-projects/spring-framework
Proposal: Support for @RecoverableBean to allow graceful initialization failure
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 60.2k
- Forks
- 38.8k
- Avg merge
- 5d 2h
- Merged PRs (30d)
- 27
Description
Problem to be solved
Currently, Spring Boot’s bean initialization process is strictly "fail-fast." If a @Bean factory method throws an exception during startup, the ApplicationContext fails to refresh, and the JVM shuts down.
While this is the correct behavior for critical infrastructure (e.g., a primary DataSource), it creates a single point of failure for non-critical peripheral services. In modern cloud-native environments, we often have beans that are "nice-to-have" but not mission-critical, such as:
- Secondary telemetry/metrics exporters.
- Third-party API clients used for non-essential features.
- Local file-system watchers or specialized cache providers that might fail due to environmental misconfiguration.
Currently, to make these "optional" at startup, developers must either:
- Wrap the entire logic in every
@Beanmethod with atry-catchand returnnull. - Use
@Lazy, which only delays the crash until runtime and prevents the use ofOptionalinjection throughout the lifecycle.
Suggested Solution
Introduce a mechanism (potentially a new annotation like @Recoverable or an attribute on @Bean) that allows a bean to fail during initialization without stopping the application.
Example Usage:
@Bean
@Recoverable
public NonCriticalService nonCriticalService() {
// If this throws an exception (e.g., ConnectionRefused), the app starts anyway.
return new NonCriticalService();
}
Proposed Behavior:
- If the factory method throws an exception, Spring catches it, logs a
WARNlevel message, and registers the bean asnull(or an emptyOptional). - Downstream beans can then inject this as
Optional<NonCriticalService>to handle the absence of the service gracefully. - This ensures the failure is contained to the specific bean and its direct dependents, rather than crashing the whole system.
Why @Lazy is not a solution
- Deferred Crashing:
@Lazymoves the failure from startup to the first request. This makes production issues harder to debug and results in "zombie" services that stay alive but crash the moment they are actually used. - Proactive Validation: We want to attempt creation at startup to verify configuration. If it fails, we want to know immediately (via logs), but we want the core application to remain available.
- Predictability:
@Recoverableallows for a predictable "null" state throughout the application's life, whereas@Lazyleaves the application in an unstable state where any thread could trigger a fatal exception at any time.
Additional Context
By making this an "opt-in" feature, we preserve Spring's default fail-fast integrity while providing a declarative way to build more resilient, fault-tolerant applications. It eliminates the boilerplate of manual try-catch blocks and makes the developer's "resilience intent" explicit in the code.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The proposal concerns Spring bean initialization during ApplicationContext refresh and @Bean factory methods; start by tracing that startup path. Before implementation, resolve the annotation or attribute and Optional/null semantics, then define tests covering a recoverable factory failure, WARN logging, and continued startup of the core application.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100