【问题标题】:How to modify the attributes of a returned object using AspectJ?如何使用 AspectJ 修改返回对象的属性?
【发布时间】:2012-11-13 22:41:23
【问题描述】:

我有一个如下所示的类(来自 Spring Roo DataOnDemand),它返回一个新的瞬态(非持久)对象以用于单元测试。这是我们从 Spring Roo 的 ITD 中推入后代码的样子。

public class MyObjectOnDemand {
    public MyObjectOnDemand getNewTransientObject(int index) {
        MyObjectOnDemand obj = new MyObjectOnDemand();
        return obj;
    }
}

我需要做的是对返回的对象引用进行额外调用,以设置 Spring Roo 的自动生成方法无法处理的额外字段。因此,在不修改上述代码(或从 Roo 的 ITD 中推入)的情况下,我想再打一个电话:

obj.setName("test_name_" + index);

为此,我声明了一个新的切面,它有正确的切入点,并会建议具体的方法。

public aspect MyObjectDataOnDemandAdvise {
    pointcut pointcutGetNewTransientMyObject() : 
        execution(public MyObject MyObjectDataOnDemand.getNewTransientObject(int));

    after() returning(MyObject obj) : 
        pointcutGetNewTransientMyObject() {
         obj.setName("test_name_" + index);
    }
}

现在,根据 Eclipse,切入点已正确编写并建议正确的方法。但它似乎并没有发生,因为持久化对象的集成测试仍然失败,因为 name 属性是必需的,但没有被设置。根据 Manning 的 AspectJ in Action(第 4.3.2 节),after 建议应该能够修改返回值。但也许我需要做一个 around() 建议?

【问题讨论】:

    标签: aspectj spring-roo pointcut


    【解决方案1】:

    我会在 tgharold 回复中添加评论,但没有足够的声誉。 (这是我的第一篇文章)

    我知道这是旧的,但我认为它可以帮助其他正在寻找这里的人知道可以使用 thisJoinPoint 在 AspectJ 中获取之前建议或之后建议中的参数。

    例如:

    after() : MyPointcut() {
        Object[] args = thisJoinPoint.getArgs();
        ...
    

    更多信息请访问:http://eclipse.org/aspectj/doc/next/progguide/language-thisJoinPoint.html

    希望它对某人有用。

    【讨论】:

      【解决方案2】:

      所以,事实证明我被 Eclipse 中的一个错误所困扰,因为它没有正确地编织东西。在 Spring Roo shell 中运行“执行测试”可以使一切正常,但是将包作为 JUnit 测试用例运行则不起作用。

      上面的代码确实可以使用“返回后”建议。但是您也可以使用“around”通知来实现它,它可以让您访问传递给方法的参数。

       MyObject around(MyObjectDataOnDemand dod, int index) :
          pointcutGetNewTransientMyObject() 
          && target(dod) && args(index) {
      
           // First, we go ahead and call the normal getNewTransient() method
           MyObject obj = proceed(dod, index);
      
           /*
           * Then we set additional properties which are required, but which
           * Spring Roo's auto-created DataOnDemand method failed to set.
           */
           obj.setName("name_" + index);
      
           // Lastly, we return the object reference
           return obj;
       }
      

      对于我们的特殊情况,“返回后”建议更加简洁易读。但了解如何使用“around”建议来访问参数也很有用。

      【讨论】:

        【解决方案3】:

        这里是使用 around 的例子:

        pointcut methodToMonitor() : execution(@Monitor * *(..));
        
        Object around() : methodToMonitor() {
            Object result=proceed();
        
            return result;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-02-06
          • 1970-01-01
          • 1970-01-01
          • 2017-05-07
          • 2021-05-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多