Home > front end >  Spring Retry: How to make all methods of a @Bean retryable?
Spring Retry: How to make all methods of a @Bean retryable?

Time:01-06

I would like to create a @Bean of a third party service like Keycloak (or any other) which may or may not be reachable at any given time. This object should retry all methods of the resulting Keycloak bean.

I have tried the following:

@Configuration
@EnableRetry
class KeycloakBeanProvider() {

    @Bean
    @Retryable
    fun keycloak(oauth2ClientRegistration: ClientRegistration): Keycloak {
        return KeycloakBuilder.builder()
            .serverUrl(serverUrl)
            .realm(oauth2ClientRegistration.clientName)
            .grantType(OAuth2Constants.CLIENT_CREDENTIALS)
            .clientId(oauth2ClientRegistration.clientId)
            .clientSecret(oauth2ClientRegistration.clientSecret)
            .build()
    }
}

But this way only the bean creation will be retried, not actual method calls on the bean. I know @Retryable can be used on class level but I don't own the Keycloak class so I can't add it there.

How can I make the methods of the resulting Keycloak bean retryable?

CodePudding user response:

You have to annotate the Keycloak with @Retryable.

@SpringBootApplication
@EnableRetry
public class So70593939Application {

    public static void main(String[] args) {
        SpringApplication.run(So70593939Application.class, args);
    }

    @Bean
    ApplicationRunner runner(Foo foo) {
        return args -> {
            foo.foo("called foo");
            foo.bar("called bar");
        };
    }

}

@Component
@Retryable
class Foo {

    public void foo(String in) {
        System.out.println("foo");
        throw new RuntimeException("test");
    }

    public void bar(String in) {
        System.out.println("bar");
        throw new RuntimeException("test");
    }

    @Recover
    public void recover(Exception ex, String in) {
        System.out.println(ex.getMessage()   ":"   in);
    }

}
foo
foo
foo
test:called foo
bar
bar
bar
test:called bar

If you can't annotate the class (e.g. because it's from another project), you need to use a RetryTemplate to call its methods instead of using annotation-based retry.

  •  Tags:  
  • Related