Simple Retry
The simplest form of retry is just to add the @Retryable
annotation to a type or method. The default behaviour of @Retryable
is to retry three times with an exponential delay of one second between each retry. (first attempt with 1s delay, second attempt with 2s delay, third attempt with 3s delay).
For example:
Simple Retry Example
@Retryable
public List<Book> listBooks() {
// ...
Simple Retry Example
@Retryable
List<Book> listBooks() {
// ...
Simple Retry Example
@Retryable
open fun listBooks(): List<Book> {
// ...
With the above example if the listBooks()
method throws a RuntimeException, it is retried until the maximum number of attempts is reached.
The multiplier
value of the @Retryable
annotation can be used to configure a multiplier used to calculate the delay between retries, allowing exponential retry support.
Note also that the @Retryable
annotation can be applied on interfaces, and the behaviour is inherited through annotation metadata. The implication of this is that @Retryable
can be used in combination with Introduction Advice such as the HTTP Client annotation.
To customize retry behaviour, set the attempts
and delay
members, For example to configure five attempts with a two second delay:
Setting Retry Attempts
@Retryable(attempts = "5",
delay = "2s")
public Book findBook(String title) {
// ...
Setting Retry Attempts
@Retryable(attempts = "5",
delay = "2s")
Book findBook(String title) {
// ...
Setting Retry Attempts
@Retryable(attempts = "5",
delay = "2s")
open fun findBook(title: String): Book {
// ...
Notice how both attempts
and delay
are defined as strings. This is to support configurability through annotation metadata. For example, you can allow the retry policy to be configured using property placeholder resolution:
Setting Retry via Configuration
@Retryable(attempts = "${book.retry.attempts:3}",
delay = "${book.retry.delay:1s}")
public Book getBook(String title) {
// ...
Setting Retry via Configuration
@Retryable(attempts = '${book.retry.attempts:3}',
delay = '${book.retry.delay:1s}')
Book getBook(String title) {
// ...
Setting Retry via Configuration
@Retryable(attempts = "\${book.retry.attempts:3}",
delay = "\${book.retry.delay:1s}")
open fun getBook(title: String): Book {
// ...
With the above in place, if book.retry.attempts
is specified in configuration it is bound to the value of the attempts
member of the @Retryable
annotation via annotation metadata.