1

I need help to write some Aspectj advice on this particular case:

Suppose we have this class:

package org.group;

public class Person {

   public void method1(String id, String number) {
       //some code
       List<String> list = getList(number);
       //some code
   }

   public List<String> getList(String number) {
       return Arrays.asList(number);
   }

}

I want to create an Aspectj advice into method1 to get the result of getList. I try this:

@Pointcut("execution(* org.group.Person.getList(..))")
public void methodGetList() {

}

@AfterReturning(pointcut = "methodGetList()", returning = "result")
public void afterMethodGetList(JoinPoint joinPoint, List<String> result) {
    System.out.println("I can see the list result: " + result.toString());
}

This advice works on all executions of getList method, but what I want exactly, is to get the result inside the method1 call to get an information with the method1's id , for example like this:


'I can see the list result [4] for the person with id : XXX'

Thank you for your help.

Tanorix
  • 230
  • 2
  • 16

1 Answers1

2

You need to limit your pointcut to the executions within the control flow - cflow() - of the calling method and also bind the calling method's parameter of interest via args().

Application:

package org.group;

import java.util.Arrays;
import java.util.List;

public class Person {
  public void method1(String id, String number) {
    // some code
    List<String> list = getList(number);
    // some code
  }

  public List<String> getList(String number) {
    return Arrays.asList(number);
  }

  public static void main(String[] args) {
    // Should not be intercepted
    new Person().getList("22");
    // Should be intercepted
    new Person().method1("John Doe", "11");
  }
}

Aspect:

package de.scrum_master.aspect;

import java.util.List;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class MyAspect {
  @Pointcut("execution(* org.group.Person.getList(..))")
  public void methodGetList() {}

  @Pointcut("execution(* org.group.Person.method1(..)) && args(id, *)")
  public void methodMethod1(String id) {}

  @AfterReturning(
    pointcut = "methodGetList() && cflow(methodMethod1(id))",
    returning = "result"
  )
  public void afterMethodGetList(JoinPoint joinPoint, String id, List<String> result) {
    System.out.println(
      "I can see the list result " + result +
      " for the person with id " + id
    );
  }
}

Console log:

I can see the list result [11] for the person with id John Doe
kriegaex
  • 63,017
  • 15
  • 111
  • 202
  • Does Spring AOP support cflow? – fg78nc Jun 20 '18 at 02:50
  • No, it does not, but you can use AspectJ via LTW in Spring. BTW, why are you tagging your question _aspectj_ and _pointcut_, but not _spring-aop_ and/or _spring_? BTW2, self-invocation like in your example would also not be intercepted in Spring AOP. So just stick with AspectJ, IMO it is better in all respects and also works without Spring. – kriegaex Jun 20 '18 at 03:44
  • It is not my question, I just commented on your answer, when I noticed AspectJ syntax within the Spring Aspect. I think you need to explain OP about LTW. – fg78nc Jun 20 '18 at 05:41
  • @fg78nc what Spring Aspect? How does Spring comes into this question or answer? – Nándor Előd Fekete Jun 20 '18 at 12:54
  • My bad, I thought he is asking about Spring. – fg78nc Jun 20 '18 at 14:27
  • Oh, @fg78nc, you are not even the original author. I mistook you for him. So the question is even more unrelated and confusing. I am happy we clarified this. So the question tags are just right, only the comment was irritating. :-) – kriegaex Jun 21 '18 at 01:54
  • @kriegaex I was confused because due `@AspectJ` syntax, which I see more often in Spring. Accustomed to AspectJ native syntax. did not pay much attention to tags.Cheers! – fg78nc Jun 22 '18 at 01:49
  • You have my sympathy. I also clearly prefer the native syntax, unlike so many others, and I will never understand why they choose otherwise. But if someone asks with annotation-based syntax (which was borrowed by Spring from AspectJ, BTW), alas I shall answer in the same style. But if I have a choice, why would I package the aspect syntax into a string instead of freely writing in my IDE editor with syntax highlighting etc.? – kriegaex Jun 22 '18 at 03:36