Search code examples
aspectjspring-aop

AspectJ: Only Rest mapped endpoints are intercepted, How to intercept internal called method?


I'm trying to intercept a method test() using annotation @Myfinder and return value Result.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Myfinder {}

@Aspect
@Component
public class MyAspect {

    @AfterReturning(value="@annotation(com.<MypackageHide>.MyFinder)",returning="result")
    public void after(JoinPoint joinPoint, Result result) {
        //something
    }

But it is intercepted only if I call it through rest api /test. I want to intercept even if this method is called from repair() method.

@RequestMapping(path = "/repair")
@RestController
@Configurable
public class MyController {

    @PostMapping("")
    public ResponseEntity<String> repair() {

        //some code
        test(); // <=============== not intercepted if i call /repair
        return ResponseEntity.ok("dummy");
    }

@MyFinder
    @PostMapping("/test") // <===== intercepted if i call this independently
    public Result test() {
        System.out.println("^^^^^^^");
        return (Result) null;
    }
    }

I want this to be called even if I call /repair

I'm fairly new to AOP


Solution

  • Spring AOP works on proxies. Calling test() from repair() is called a self-invocation. Spring AOP will not be able to advice the method call to test() from repair() , as it will not go through the proxy.

    Spring reference documentation : Understanding AOP Proxies . Read through the section starting with The key thing to understand here is that the client code inside the main(..)

    If you still wants to intercept and advice such a method call , you can autowire the controller instance to the same class as follows. I would recommended you to refactor the code , but to demonstrate the possibility , following code would work.

    @RequestMapping(path = "/repair")
    @RestController
    @Configurable
    public class MyController {
        @Autowired
        MyController self;
    
        @PostMapping("")
        public ResponseEntity<String> repair() {
    
            //some code
            self.test(); // <=============== self reference
            return ResponseEntity.ok("dummy");
        }
    
    @MyFinder
        @PostMapping("/test") // <===== intercepted if i call this independently
        public Result test() {
            System.out.println("^^^^^^^");
            return (Result) null;
        }
        }