【问题标题】:AspectJ: Intercept return result of method inside another methodAspectJ:在另一个方法中截取方法的返回结果
【发布时间】:2018-06-19 10:13:17
【问题描述】:

我需要帮助来写一些关于这个特殊案例的 Aspectj 建议:

假设我们有这个类:

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);
   }

}

我想在 method1 中创建一个 Aspectj 建议以获取 getList 的结果。我试试这个:

@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());
}

此建议适用于 getList 方法的所有执行,但我真正想要的是在 method1 调用中获取结果,以获取带有 method1 的 id 的信息,例如:


'我可以看到ID为:XXX的人的列表结果[4]'

感谢您的帮助。

【问题讨论】:

    标签: java aspectj pointcut pointcuts


    【解决方案1】:

    您需要将切入点限制在控制流中的执行 - cflow() - 调用方法,并通过 args() 绑定调用方法的感兴趣参数。

    应用:

    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");
      }
    }
    

    方面:

    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
        );
      }
    }
    

    控制台日志:

    I can see the list result [11] for the person with id John Doe
    

    【讨论】:

    • Spring AOP 支持 cflow 吗?
    • 不,它没有,但您可以在 Spring 中通过 LTW 使用 AspectJ。顺便说一句,你为什么要标记你的问题 aspectjpointcut,而不是 spring-aop 和/或 spring? BTW2,像你的例子中的自我调用也不会在 Spring AOP 中被拦截。所以坚持使用 AspectJ,IMO 它在所有方面都更好,并且在没有 Spring 的情况下也可以工作。
    • 这不是我的问题,当我注意到 Spring Aspect 中的 AspectJ 语法时,我只是评论了你的答案。我认为你需要解释一下关于 LTW 的 OP。
    • @fg78nc 什么是 Spring Aspect? Spring是如何进入这个问题或答案的?
    • 我的错,我以为他在问 Spring。
    猜你喜欢
    • 2022-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-01
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    相关资源
    最近更新 更多