0

I was trying to create an aspect around custom annotation to add some extra logic. But i faced an issue when an aspect wasn't created for a method call testRetrMethods.callWithRetriable()

My code is the following: Controller class

@RestController
 @RequestMapping("/author")
 public class AuthorController {

    @Autowired
    private TestRetrMethods testRetrMethods;

    @GetMapping
    public String printBooks() {
        return testRetrMethods.callWithRetriable();
    }}

And TestRetrMethods bean:

@Slf4j
@Component
public class TestRetrMethods {


    public String callWithRetriable() {
        String result = null;
        try {
            result = testRetriesAttempts();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return result;
    }

    @AwsRetryable
    public String testRetriesAttempts() throws ExecutionException {

        throw new ExecutionException("This is test exception", new ResourceExistsException("This is " +
                "real example"));

    }
}

Annotation:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AwsRetryable {
    int maxAttempts() default 3;

Aspect itself:

@Aspect
@Component
public class RetryableAspect {
    
    @Around("@annotation(AwsRetryable)")
    public Object catchMethod(ProceedingJoinPoint point) throws Throwable {
        String methodName = getMethod(point).getName();
        log.info("Initializing retryable proxy over method: " + methodName);
        AwsRetryOperationProcessor operationProcessor = new AwsRetryOperationProcessor(
                readAnnotation(point), getMethod(point).getName());
        return operationProcessor.process(point);
    }

Application class:

@SpringBootApplication
@EnableAspectJAutoProxy
public class BookStoreApplication {

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

The issue is that aspect wasn't created for testRetriesAttempts() method call. But if i annotate callWithRetriable() with @AwsRetryable then it would be created. I've tried different solutions, like creating a pointcut

@Pointcut("execution(@AwsRetryable * *.*(..))")
    public void annotatedMethod() {
    }

but it didn't help. Would appreciate any help with this.

user3411289
  • 123
  • 1
  • 1
  • 6
  • IIRC, Spring AOP only works for calls between components; you call your test method from the same component. Try annotating `callWithRetriable()`, that should trigger the aspect when called from the controller. – daniu Feb 22 '22 at 11:49
  • that is the trick, it's a inner method that shares common logic. Will try might to do it with inner class. – user3411289 Feb 22 '22 at 13:09
  • Spring AOP cannot advice a self-invocation . Also it can only advice a Spring container managed bean . If the inner classes mentioned here is not a bean , then it will not work. Do go through : [5.8.1. Understanding AOP Proxies](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop-understanding-aop-proxies) – R.G Feb 23 '22 at 01:46
  • AspectJ can help achieve this usecase – R.G Feb 24 '22 at 07:49

0 Answers0