In my project I have a Feign client extending API interface generated from OpenAPI spec:
@FeignClient(name = "customerClient", url = "${spring.microservice.tenant-service-gateway.host}", configuration = FeignConfiguration.class)
public interface CustomerClient extends CustomersApi {
}
FeignConfiguration
introduces retry config for 500
response code:
@Configuration
@EnableAspectJAutoProxy
public class FeignConfiguration {
@Bean
public Retryer httpResponseCodeRetryer(
@Value("${feign.max-attempt-count}") int retryCount,
@Value("${feign.retry-period-seconds}") int retryPeriod
) {
return new Retryer.Default(TimeUnit.SECONDS.toMillis(retryPeriod), TimeUnit.SECONDS.toMillis(3L), retryCount);
}
@Bean
public ErrorDecoder httpCodeErrorDecoder() {
return new HttpCodeErrorDecoder();
}
static class HttpCodeErrorDecoder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
var exception = feign.FeignException.errorStatus(methodKey, response);
int status = response.status();
if (status == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
return new RetryableException(
response.status(),
exception.getMessage(),
response.request().httpMethod(),
exception,
null,
response.request());
}
return exception;
}
}
}
What I want is to add retry functionality for 202
response code either. To achieve this I add this pointcut:
@Aspect
public class AfterReturningExample {
@Around("execution(* com.project.client.CustomerClient.*(..))")
public Object customerClient(ProceedingJoinPoint pjp) throws Throwable {
var proceed = pjp.proceed();
//some logic here
return proceed;
}
}
I've tried to solve this by adding pointcut for the methods of CustomersApi
like this:
@Around("execution(* com.project.api.CustomersApi+.*(..))")
public Object customerApi(ProceedingJoinPoint pjp) throws Throwable {
var proceed = pjp.proceed();
//some logic here
return proceed;
}
If there is only an @Aspect
on your class it won't be detected and as such nothing will be applied as Spring AOP doesn't see it.
You can add @Component
to your @Aspect
annotated class which will make it available to Spring.
@Component
@Aspect
public class AfterReturningExample { ... }
Another option is to write an includeFilter
in an @ComponentScan
to include all classes annotated with @Aspect
.
@SpringBootApplication
@ComponentScan(includeFilter= { @Filter(type = FilterType.ANNOTATION, value=org.aspectj.lang.annotation.Aspect )}
With this classes annotated with @Aspect
(and not with @Component
) will be included as well.
Either way will work.