1

In a Spring Boot project I have a simple feign client

@MyAnnotation
@FeignClient(name="some-name", url="http://test.url")
public interface MyClient {
    @RequestMapping(method = RequestMethod.GET, value = "/endpoint")
    List<Store> getSomething();
}

I need to intercept all calls and for this and I'm creating a common library that can be used in different projects. To achieve it I try to use Spring AOP. I created an aspect that wraps all public methods of the object annotated with MyAnnotation

@Around("@within(MyAnnotation) && execution(public * *(..))")
public Object myWrapper(ProceedingJoinPoint invocation) throws Throwable {
   // ...
}

It works correctly and all calls are intercepted till I tried to put MyAnnotation on the feign client that uses inheritance for feign interfaces. When I init my client with inherited interface calls are not intercepted anymore.

public interface FeignClientInterface {
    @RequestMapping(method = RequestMethod.GET, value = "/endpoint")
    List<Store> getSomething();
}

@MyAnnotation
@FeignClient(name="some-name", url="http://test.url")
public interface MyClient extends FeignClientInterface{ 
}

I tried:

  • "@target(MyAnnotation) && execution(public * *(..))" but when I connected my library to the real project I got java.lang.IllegalArgumentException: Cannot subclass final class org.springframework.boot.autoconfigure.AutoConfigurationPackages$BasePackages It seems that it wanted to wrap all to the proxy and there were final classes.
  • "@target(MyAnnotation) && execution(public * com.my.company.base.package.*(..))" removed previous issue but gave another one, like some bean cannot be instantiated without name, etc.

The question is how to make it work without moving @MyAnnotation to the base interface FeignClientInterface. It is in another project and I don't have a control on it.

Vitalii
  • 10,091
  • 18
  • 83
  • 151

1 Answers1

0

Ok, after hours of investigation I replaced my pointcut with this one

@Around("execution(* (@MyAnnotation *).*(..)) || execution(@MyAnnotation * *(..))")

As explained here I used only execution to avoid proxy creation.

Vitalii
  • 10,091
  • 18
  • 83
  • 151
  • Good that you found the solution . Out of curiosity I have been trying to debug this issue. Could you please check and let me know if the following pointcut resolves the issue for you ? `(@target(MyAnnotation) && within(com.my.company.base.package..*))`. I could reproduce your issue with `@target` alone , but it goes off when I introduce the scoping designator `within`. – R.G Apr 25 '20 at 11:47
  • I tried this and this can work if you don't have final classes or other proxies in `com.my.company.base.package`. I needed to include it in a big project and and when I did it I got `java.lang.IllegalArgumentException: Cannot subclass final class org.springframework.cloud.sleuth.log.Slf4jScopeDecorator` But this worked perfectly in my library and created unit tests were all successfull – Vitalii Apr 25 '20 at 13:40
  • As far as I understood, when we use `@target` Spring creates a proxies for all possible beans. In a big project there were some final classes, etc. – Vitalii Apr 25 '20 at 13:42
  • Thank you for the update. I tried to recreate the case with a final class within the scope and adding `within()` to the pointcut tend to resolve the issue . Yours is a real project and the complexity would be definitely higher. – R.G Apr 25 '20 at 13:55
  • Yes, it will work for 99% of cases but I got a chance to fall into 1% :) Final beans, feign clients, some other aspects, a lot of other stuff I'm not familiar with inside the project. Thanks for trying to help anyway :) – Vitalii Apr 25 '20 at 13:59