CtrlK
CommunityDocumentationLog inGet started
Tessl Logo

tessl/maven-org-springframework-ai--spring-ai-autoconfigure-retry

Spring Boot auto-configuration for AI retry capabilities with exponential backoff and intelligent HTTP error handling

Overview
Eval results
Files

api-overview.mddocs/reference/

Spring AI Retry Auto Configuration

Spring AI Retry Auto Configuration provides Spring Boot auto-configuration for AI retry capabilities within the Spring AI framework. It automatically configures a RetryTemplate with exponential backoff for handling transient failures when communicating with AI model providers, and implements intelligent HTTP error handling through a ResponseErrorHandler that distinguishes between transient errors (which should be retried) and non-transient errors (which should fail immediately).

Package Information

  • Group ID: org.springframework.ai
  • Artifact ID: spring-ai-autoconfigure-retry
  • Package Type: Maven
  • Language: Java
  • Version: 1.1.2
  • License: Apache-2.0
  • Installation: Add the following dependency to your Maven project:
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-autoconfigure-retry</artifactId>
    <version>1.1.2</version>
</dependency>

For Gradle:

implementation 'org.springframework.ai:spring-ai-autoconfigure-retry:1.1.2'

Core Imports

The auto-configuration automatically provides beans when the library is on the classpath. To use the beans in your application:

import org.springframework.retry.support.RetryTemplate;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.beans.factory.annotation.Autowired;

To access exception types for custom error handling:

import org.springframework.ai.retry.TransientAiException;
import org.springframework.ai.retry.NonTransientAiException;

To access utility constants:

import org.springframework.ai.retry.RetryUtils;

To use configuration properties:

import org.springframework.ai.retry.autoconfigure.SpringAiRetryProperties;

Additional imports for Spring framework components:

import org.springframework.web.client.ResourceAccessException;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.HttpMethod;
import java.net.URI;
import java.io.IOException;

For WebFlux support (optional):

import org.springframework.web.reactive.function.client.WebClientRequestException;

Basic Usage

The auto-configuration automatically creates and configures beans when the library is on the classpath. No explicit configuration is required for default behavior.

Automatic Bean Configuration

When the module is on the classpath, Spring Boot automatically:

  1. Creates a RetryTemplate bean with exponential backoff (bean name: "retryTemplate")
  2. Creates a ResponseErrorHandler bean for HTTP error classification (bean name: "responseErrorHandler")
  3. Makes these beans available for injection into your components

Using the Auto-Configured RetryTemplate

import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Service;

@Service
public class AiService {

    private final RetryTemplate retryTemplate;

    public AiService(RetryTemplate retryTemplate) {
        this.retryTemplate = retryTemplate;
    }

    public String callAiModel() {
        return retryTemplate.execute(context -> {
            // Call to AI model that may throw TransientAiException
            // context.getRetryCount() returns the current retry attempt (0-based)
            // context.getLastThrowable() returns the last exception thrown
            return makeAiApiCall();
        });
    }

    private String makeAiApiCall() {
        // Implementation that may throw TransientAiException
        return "AI response";
    }
}

The RetryTemplate.execute() method signature:

/**
 * Executes the callback with retry support
 * @param callback RetryCallback to execute
 * @param <T> Return type
 * @param <E> Exception type
 * @return Result from callback
 * @throws E if all retries are exhausted or non-retryable exception occurs
 */
<T, E extends Throwable> T execute(RetryCallback<T, E> callback) throws E;

Using the Auto-Configured ResponseErrorHandler

import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RestTemplateConfig {

    private final ResponseErrorHandler responseErrorHandler;

    public RestTemplateConfig(ResponseErrorHandler responseErrorHandler) {
        this.responseErrorHandler = responseErrorHandler;
    }

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        // Set the error handler - it will throw TransientAiException or NonTransientAiException
        restTemplate.setErrorHandler(responseErrorHandler);
        return restTemplate;
    }
}

Customizing Retry Behavior via Properties

Configure retry behavior in application.properties:

# Maximum number of retry attempts (default: 10)
spring.ai.retry.max-attempts=10

# Retry on 4xx client errors (default: false)
spring.ai.retry.on-client-errors=false

# HTTP codes that should trigger a retry (comma-separated)
spring.ai.retry.on-http-codes=429,503

# HTTP codes that should NOT trigger a retry (comma-separated)
spring.ai.retry.exclude-on-http-codes=401,403

# Backoff configuration
spring.ai.retry.backoff.initial-interval=2000ms
spring.ai.retry.backoff.multiplier=5
spring.ai.retry.backoff.max-interval=180000ms

Or in application.yml:

spring:
  ai:
    retry:
      max-attempts: 10
      on-client-errors: false
      on-http-codes:
        - 429
        - 503
      exclude-on-http-codes:
        - 401
        - 403
      backoff:
        initial-interval: 2000ms
        multiplier: 5
        max-interval: 180000ms

Architecture

The module consists of three main layers:

  1. Auto-Configuration Layer (SpringAiRetryAutoConfiguration): Provides Spring Boot auto-configuration that automatically creates and configures beans when the library is detected on the classpath
  2. Configuration Layer (SpringAiRetryProperties): Manages all retry configuration through Spring Boot's property binding system with the prefix spring.ai.retry
  3. Runtime Layer (Exception types and utility classes): Provides exception types for error classification and utility constants for common retry scenarios

The auto-configuration integrates with:

  • Spring Retry: Uses RetryTemplate for retry logic with exponential backoff
  • Spring MVC: Provides ResponseErrorHandler for RestTemplate HTTP error handling
  • Spring WebFlux: Optionally handles WebClient exceptions when WebFlux is on the classpath
  • Spring Boot: Uses auto-configuration discovery and property binding

Auto-Configuration Discovery

The auto-configuration is registered in:

  • File: META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  • Content: org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration

Spring Boot automatically discovers and applies this auto-configuration when:

  1. The library is on the classpath
  2. RetryUtils.class is available (from spring-ai-retry dependency)
  3. No custom beans are defined (due to @ConditionalOnMissingBean)

Capabilities

Auto-Configuration

Automatic configuration of retry beans for Spring AI applications. The auto-configuration conditionally creates beans only when they are not already defined, allowing for custom override.

// Package: org.springframework.ai.retry.autoconfigure
@AutoConfiguration
@ConditionalOnClass(RetryUtils.class)
@EnableConfigurationProperties({ SpringAiRetryProperties.class })
public class SpringAiRetryAutoConfiguration {

    /**
     * Creates a RetryTemplate bean with exponential backoff
     * Bean name: "retryTemplate"
     * Condition: Created only if no RetryTemplate bean exists
     * 
     * Configured to retry on:
     * - TransientAiException
     * - ResourceAccessException (Spring's network error exception)
     * - WebClientRequestException (if WebFlux is on classpath)
     * 
     * Uses exponential backoff with parameters from properties:
     * - initial interval (default: 2000ms)
     * - multiplier (default: 5)
     * - max interval (default: 180000ms)
     * 
     * Includes retry listener that logs: "Retry error. Retry count: {count}, Exception: {message}"
     * 
     * @param properties Configuration properties for retry behavior
     * @return Configured RetryTemplate instance
     */
    @Bean
    @ConditionalOnMissingBean
    public RetryTemplate retryTemplate(SpringAiRetryProperties properties);

    /**
     * Creates a ResponseErrorHandler bean for HTTP error classification
     * Bean name: "responseErrorHandler"
     * Condition: Created only if no ResponseErrorHandler bean exists
     * 
     * Classifies HTTP errors based on configuration:
     * 1. Status in onHttpCodes → TransientAiException (retry)
     * 2. Status in excludeOnHttpCodes → NonTransientAiException (no retry)
     * 3. 4xx when onClientErrors=false → NonTransientAiException (no retry)
     * 4. All other errors → TransientAiException (retry)
     * 
     * Error message format: "HTTP {status_code} - {response_body}"
     * If response body is empty: "HTTP {status_code} - No response body available"
     * 
     * @param properties Configuration properties for error handling behavior
     * @return Configured ResponseErrorHandler instance
     */
    @Bean
    @ConditionalOnMissingBean
    public ResponseErrorHandler responseErrorHandler(SpringAiRetryProperties properties);
}

The retryTemplate bean is configured to:

  • Retry on TransientAiException and ResourceAccessException
  • Optionally retry on WebClientRequestException when WebFlux is available
  • Use exponential backoff with configurable parameters
  • Log warnings on each retry attempt with format: "Retry error. Retry count: " + context.getRetryCount() + ", Exception: " + throwable.getMessage()

The responseErrorHandler bean classifies HTTP errors as:

  • Transient (retry): Server errors (5xx), configured codes in onHttpCodes, optionally 4xx when onClientErrors=true
  • Non-transient (fail): 4xx client errors (when onClientErrors=false), configured codes in excludeOnHttpCodes

Auto-Configuration Details

Configuration Properties

Comprehensive configuration options for customizing retry behavior including max attempts, backoff parameters, and HTTP status code handling.

// Package: org.springframework.ai.retry.autoconfigure
@ConfigurationProperties("spring.ai.retry")
public class SpringAiRetryProperties {

    /**
     * Configuration prefix for all retry properties
     * Value: "spring.ai.retry"
     */
    public static final String CONFIG_PREFIX = "spring.ai.retry";

    /**
     * Gets the maximum number of retry attempts
     * Default value: 10
     * Minimum recommended: 1
     * Maximum recommended: 100
     * 
     * @return Maximum retry attempts (default: 10)
     */
    public int getMaxAttempts();

    /**
     * Sets the maximum number of retry attempts
     * @param maxAttempts Maximum retry attempts (must be >= 0)
     */
    public void setMaxAttempts(int maxAttempts);

    /**
     * Gets the backoff configuration
     * Marked with @NestedConfigurationProperty for Spring Boot configuration metadata
     * Never returns null - always returns a valid Backoff instance
     * 
     * @return Backoff configuration object
     */
    public Backoff getBackoff();

    /**
     * Gets whether to retry on 4xx client errors
     * If false (default): 4xx errors throw NonTransientAiException (no retry)
     * If true: 4xx errors throw TransientAiException (retry)
     * Exception: Codes in excludeOnHttpCodes always throw NonTransientAiException
     * Exception: Codes in onHttpCodes always throw TransientAiException
     * 
     * @return true to retry on 4xx, false to treat as non-transient (default: false)
     */
    public boolean isOnClientErrors();

    /**
     * Sets whether to retry on 4xx client errors
     * @param onClientErrors true to retry on 4xx, false to treat as non-transient
     */
    public void setOnClientErrors(boolean onClientErrors);

    /**
     * Gets the list of HTTP codes that should NOT trigger retry
     * Takes lower precedence than onHttpCodes
     * Common values: 401, 403, 400, 404
     * Default: empty list
     * 
     * @return List of HTTP status codes to treat as non-transient (never null)
     */
    public List<Integer> getExcludeOnHttpCodes();

    /**
     * Sets the list of HTTP codes that should NOT trigger retry
     * @param excludeOnHttpCodes List of HTTP status codes to treat as non-transient
     */
    public void setExcludeOnHttpCodes(List<Integer> excludeOnHttpCodes);

    /**
     * Gets the list of HTTP codes that should trigger retry
     * Takes highest precedence in error classification
     * Common values: 429 (rate limit), 503 (service unavailable)
     * Default: empty list
     * 
     * @return List of HTTP status codes to treat as transient (never null)
     */
    public List<Integer> getOnHttpCodes();

    /**
     * Sets the list of HTTP codes that should trigger retry
     * @param onHttpCodes List of HTTP status codes to treat as transient
     */
    public void setOnHttpCodes(List<Integer> onHttpCodes);
}

Configuration Properties Details

Exception Handling

Exception types for classifying errors as transient or non-transient to control retry behavior. Both exception types are from the spring-ai-retry module.

// Package: org.springframework.ai.retry
/**
 * Exception for transient AI errors where retry might succeed
 * Extends: java.lang.RuntimeException (unchecked exception)
 * 
 * Use cases:
 * - Server errors (5xx)
 * - Network timeouts
 * - Rate limiting (429)
 * - Temporary service unavailability (503)
 * - Connection errors
 * 
 * Behavior with RetryTemplate:
 * - Triggers retry if attempts remain
 * - Propagated to caller if all retries exhausted
 * 
 * @since 0.8.1
 */
public class TransientAiException extends RuntimeException {
    
    /**
     * Constructs exception with message only
     * @param message Error message describing the transient failure
     */
    public TransientAiException(String message);
    
    /**
     * Constructs exception with message and underlying cause
     * @param message Error message describing the transient failure
     * @param cause The underlying cause of the exception (can be null)
     */
    public TransientAiException(String message, Throwable cause);
}

/**
 * Exception for non-transient AI errors where retry will not help
 * Extends: java.lang.RuntimeException (unchecked exception)
 * 
 * Use cases:
 * - Authentication errors (401)
 * - Authorization errors (403)
 * - Bad request errors (400)
 * - Not found errors (404)
 * - Client configuration errors
 * 
 * Behavior with RetryTemplate:
 * - Causes immediate failure without retry
 * - Propagated to caller immediately
 * 
 * @since 0.8.1
 */
public class NonTransientAiException extends RuntimeException {
    
    /**
     * Constructs exception with message only
     * @param message Error message describing the non-transient failure
     */
    public NonTransientAiException(String message);
    
    /**
     * Constructs exception with message and underlying cause
     * @param message Error message describing the non-transient failure
     * @param cause The underlying cause of the exception (can be null)
     */
    public NonTransientAiException(String message, Throwable cause);
}

Exception Handling Details

Retry Utilities

Abstract utility class from the spring-ai-retry module providing default retry templates and error handlers for common use cases.

// Package: org.springframework.ai.retry
/**
 * RetryUtils is a utility class for configuring and handling retry operations
 * This is an abstract class - cannot be instantiated
 * All members are static constants
 * 
 * @since 0.8.1
 */
public abstract class RetryUtils {

    /**
     * Default retry template with production-ready settings
     * Configuration:
     * - Max attempts: 10
     * - Retries on: TransientAiException, ResourceAccessException
     * - Exponential backoff: initial 2s, multiplier 5, max 3min
     * - Backoff progression: 2s, 10s, 50s, 180s (capped), 180s, ...
     * 
     * Type: org.springframework.retry.support.RetryTemplate
     * Thread-safe: Yes (immutable once created)
     */
    public static final RetryTemplate DEFAULT_RETRY_TEMPLATE;

    /**
     * Retry template for testing with short delays
     * Configuration:
     * - Max attempts: 10
     * - Retries on: TransientAiException, ResourceAccessException
     * - Fixed backoff: 100ms (no exponential growth)
     * - Total max time: ~1 second for all retries
     * 
     * Use in unit/integration tests to avoid long wait times
     * 
     * Type: org.springframework.retry.support.RetryTemplate
     * Thread-safe: Yes (immutable once created)
     */
    public static final RetryTemplate SHORT_RETRY_TEMPLATE;

    /**
     * Default response error handler for HTTP errors
     * Behavior:
     * - 4xx errors → Throws NonTransientAiException (no retry)
     * - 5xx errors → Throws TransientAiException (retry)
     * - Error message format: "{status_code} - {response_body}"
     * - Reads response body as UTF-8 String
     * 
     * Implements: org.springframework.web.client.ResponseErrorHandler
     * Thread-safe: Yes (stateless implementation)
     * 
     * Methods implemented:
     * - boolean hasError(ClientHttpResponse response)
     * - void handleError(ClientHttpResponse response)
     * - void handleError(URI url, HttpMethod method, ClientHttpResponse response)
     */
    public static final ResponseErrorHandler DEFAULT_RESPONSE_ERROR_HANDLER;
}

ResponseErrorHandler Interface Methods:

The DEFAULT_RESPONSE_ERROR_HANDLER implements the following interface methods:

/**
 * Checks if the response has an error status code
 * Implementation: Returns response.getStatusCode().isError()
 * Returns true for all 4xx and 5xx status codes
 * 
 * @param response The client HTTP response
 * @return true if response status code is an error (4xx or 5xx)
 * @throws IOException if an I/O error occurs reading the response
 */
boolean hasError(ClientHttpResponse response) throws IOException;

/**
 * Handles the error in the given response
 * Reads response body and throws appropriate exception:
 * - 4xx → NonTransientAiException
 * - 5xx → TransientAiException
 * 
 * Error message includes status code and response body text
 * 
 * @param response The client HTTP response with error
 * @throws IOException if an I/O error occurs reading the response
 * @throws NonTransientAiException for 4xx client errors
 * @throws TransientAiException for 5xx server errors
 */
void handleError(ClientHttpResponse response) throws IOException;

/**
 * Handles the error in the given response with additional context
 * Delegates to handleError(ClientHttpResponse) after logging context
 * 
 * @param url The URL that was called
 * @param method The HTTP method that was used (GET, POST, etc.)
 * @param response The client HTTP response with error
 * @throws IOException if an I/O error occurs reading the response
 * @throws NonTransientAiException for 4xx client errors
 * @throws TransientAiException for 5xx server errors
 */
void handleError(URI url, HttpMethod method, ClientHttpResponse response) throws IOException;

The utility class provides pre-configured constants that can be used directly without Spring Boot auto-configuration.

Types

Backoff Configuration

Nested static class within SpringAiRetryProperties for exponential backoff configuration.

// Package: org.springframework.ai.retry.autoconfigure
// Nested within: SpringAiRetryProperties
/**
 * Configuration for exponential backoff behavior
 * Nested static class within SpringAiRetryProperties
 * 
 * Backoff formula: wait_time = min(initial_interval × multiplier^(retry_count - 1), max_interval)
 */
public static class Backoff {

    /**
     * Gets the initial sleep duration before first retry
     * Default: Duration.ofMillis(2000) = 2 seconds
     * Minimum recommended: 100ms
     * Maximum recommended: 60s
     * 
     * @return Initial backoff duration (default: 2 seconds)
     */
    public Duration getInitialInterval();

    /**
     * Sets the initial sleep duration before first retry
     * @param initialInterval Initial backoff duration (must not be null or negative)
     */
    public void setInitialInterval(Duration initialInterval);

    /**
     * Gets the backoff interval multiplier for exponential growth
     * Default: 5
     * Typical values: 2 (moderate growth), 3-5 (aggressive growth), 1 (fixed backoff)
     * 
     * Example with multiplier=5, initial=2s:
     * Retry 1: 2s
     * Retry 2: 10s (2 × 5)
     * Retry 3: 50s (10 × 5)
     * Retry 4: 180s (50 × 5, capped at maxInterval)
     * 
     * @return Multiplier value (default: 5)
     */
    public int getMultiplier();

    /**
     * Sets the backoff interval multiplier for exponential growth
     * @param multiplier Multiplier value (must be >= 1)
     */
    public void setMultiplier(int multiplier);

    /**
     * Gets the maximum backoff duration
     * Default: Duration.ofMillis(180000) = 3 minutes
     * Prevents unbounded exponential growth
     * Minimum recommended: 1s
     * Maximum recommended: 15 minutes
     * 
     * @return Maximum backoff duration (default: 3 minutes)
     */
    public Duration getMaxInterval();

    /**
     * Sets the maximum backoff duration
     * @param maxInterval Maximum backoff duration (must not be null or negative)
     */
    public void setMaxInterval(Duration maxInterval);
}

Dependencies

This module depends on:

  • org.springframework.ai:spring-ai-retry - Core retry utilities and exception types (required)
  • org.springframework.boot:spring-boot-starter - Spring Boot core functionality (required)
  • Spring Retry framework (transitive from spring-ai-retry) - Provides RetryTemplate and retry logic (required)

Optional dependencies:

  • Spring WebFlux - For WebClient exception handling support (optional, auto-detected at runtime)

Maven dependency tree:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-autoconfigure-retry</artifactId>
    <version>1.1.2</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-retry</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!-- Transitive: Spring Retry -->
    </dependencies>
</dependency>

Integration Notes

RestTemplate Integration

The auto-configured ResponseErrorHandler can be set on any RestTemplate:

import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate aiRestTemplate(ResponseErrorHandler errorHandler) {
        RestTemplate restTemplate = new RestTemplate();
        // Error handler will be invoked on 4xx and 5xx responses
        // Before the response is returned to the caller
        restTemplate.setErrorHandler(errorHandler);
        return restTemplate;
    }
}

WebClient Integration

When Spring WebFlux is on the classpath, the auto-configured RetryTemplate automatically includes retry behavior for WebClientRequestException.

WebFlux detection code:

// In SpringAiRetryAutoConfiguration
try {
    Class<?> webClientRequestEx = Class.forName(
        "org.springframework.web.reactive.function.client.WebClientRequestException"
    );
    // If class found, add it to retryable exceptions
    retryTemplateBuilder.retryOn(webClientRequestEx);
} catch (ClassNotFoundException ignore) {
    // WebFlux not on classpath; skip WebClient support
}

Custom Bean Override

To provide custom implementations, define your own beans. The auto-configuration will detect them and skip creating its own due to @ConditionalOnMissingBean.

import org.springframework.retry.support.RetryTemplate;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CustomRetryConfig {

    /**
     * Custom RetryTemplate overrides auto-configured bean
     * This bean will be used instead of the auto-configured one
     */
    @Bean
    public RetryTemplate retryTemplate() {
        // Custom RetryTemplate configuration
        return RetryTemplate.builder()
            .maxAttempts(5)
            .fixedBackoff(1000)
            .build();
    }

    /**
     * Custom ResponseErrorHandler overrides auto-configured bean
     * This bean will be used instead of the auto-configured one
     */
    @Bean
    public ResponseErrorHandler responseErrorHandler() {
        // Custom ResponseErrorHandler implementation
        return new MyCustomErrorHandler();
    }
}

The auto-configuration will detect these beans and skip creating its own due to @ConditionalOnMissingBean annotations.

Multiple RestTemplate Beans

If you need multiple RestTemplate beans with different error handlers:

import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.beans.factory.annotation.Qualifier;

@Configuration
public class MultipleRestTemplateConfig {

    /**
     * RestTemplate with auto-configured error handler for AI calls
     */
    @Bean
    @Qualifier("aiRestTemplate")
    public RestTemplate aiRestTemplate(ResponseErrorHandler errorHandler) {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setErrorHandler(errorHandler);
        return restTemplate;
    }

    /**
     * RestTemplate with default error handler for other API calls
     */
    @Bean
    @Qualifier("defaultRestTemplate")
    public RestTemplate defaultRestTemplate() {
        // Uses Spring's default error handler
        return new RestTemplate();
    }
}

Programmatic RetryTemplate Usage

Advanced usage with RetryCallback and RecoveryCallback:

import org.springframework.retry.support.RetryTemplate;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RecoveryCallback;
import org.springframework.retry.RetryContext;

public class AdvancedRetryUsage {

    private final RetryTemplate retryTemplate;

    public String callWithRecovery() {
        return retryTemplate.execute(
            // RetryCallback: main operation
            new RetryCallback<String, RuntimeException>() {
                @Override
                public String doWithRetry(RetryContext context) throws RuntimeException {
                    // context.getRetryCount() = current attempt (0-based)
                    // context.getLastThrowable() = last exception
                    return performApiCall();
                }
            },
            // RecoveryCallback: fallback if all retries fail
            new RecoveryCallback<String>() {
                @Override
                public String recover(RetryContext context) throws Exception {
                    // Called after all retries exhausted
                    return "Fallback response";
                }
            }
        );
    }

    private String performApiCall() {
        // Implementation
        return "result";
    }
}

Lambda syntax:

public String callWithRecoveryLambda() {
    return retryTemplate.execute(
        context -> performApiCall(),  // RetryCallback
        context -> "Fallback response"  // RecoveryCallback
    );
}
tessl i tessl/maven-org-springframework-ai--spring-ai-autoconfigure-retry@1.1.1

docs

index.md

tile.json