Add resilience: Spring Framework 7 @Retryable and @ConcurrencyLimit
Companion code for "Spring Framework 7's Built-in Resilience: @Retryable, @ConcurrencyLimit, and What's Left for Resilience4j". Every retry counted by recording real invocations: defaults, backoff and jitter, timeout, reactive and CompletableFuture returns, the concurrency limit's BLOCK and REJECT policies, retries around transactions, composition with Resilience4j 2.4.0, and the annotation API across 7.0.0-7.0.9. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01C3TETMrqVUWeFkNtz3Jbo3
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
# 2. Switching it on - and the three ways it stays off
|
||||
|
||||
[← 1. What ships](01-whats-in-framework-7.md) · [Index](../README.md) · Next: [3. @Retryable measured →](03-retryable-measured.md)
|
||||
|
||||
## Spring Boot 4.1.1 does not enable it
|
||||
|
||||
No auto-configuration in Boot 4.1.1 registers `RetryAnnotationBeanPostProcessor` or
|
||||
`ConcurrencyLimitBeanPostProcessor` (no Boot 4.1.1 jar in this project's dependency tree mentions
|
||||
either class). You need [`@EnableResilientMethods`](../src/main/java/com/ankurm/resilience/ResilienceConfig.java).
|
||||
|
||||
Without it the annotations are metadata. [`retry-disabled.txt`](output/retry-disabled.txt), same
|
||||
method, `demo.resilience.enabled=false`:
|
||||
|
||||
```
|
||||
"invocations": 1,
|
||||
"caller": "threw: com.ankurm.resilience.support.TransientException: attempt 1 failed"
|
||||
```
|
||||
|
||||
No warning at startup, no log line at call time.
|
||||
|
||||
## Self-invocation
|
||||
|
||||
A call from inside the bean does not go through the proxy
|
||||
([`retry-self-invocation.txt`](output/retry-self-invocation.txt)): one invocation, first exception
|
||||
straight to the caller. Same rule as `@Transactional` and `@Async` - see the
|
||||
[AOP article](https://ankurm.com/spring-aop-pointcuts-advice-types-aspect-not-firing/).
|
||||
|
||||
## `final` methods
|
||||
|
||||
The proxies here are CGLIB subclasses (`/demo/proxy/*` reports the type - the demo beans implement
|
||||
no interface). A subclass cannot override a `final` method, so a `final @Retryable` method is
|
||||
called directly on the target and never retried - the same silent failure measured for `@Async` in
|
||||
the [@Async article](https://ankurm.com/spring-boot-4-async-executors-virtual-threads/).
|
||||
Reference in New Issue
Block a user