0

java.util.Set就我而言,我通过建议对 的实例(尤其是add(Object)和)的某些方法调用来跟踪某些集合的更改remove(Object)。由于更改未反映在集合本身中,因此调用Set.contains(Object)Set.size()返回错误结果。

因此,我想拦截对 Set 实例的所有方法调用(除了addand remove),并将调用转发到我的最新集合。

当然,我可以使用不同的切入点定义两个建议,如下所示:

// matches Collection.size(), Collection.isEmpty(), ...
* around(Collection c) : call(* Collection.*()) && target(c)
            && !remove(/*...*/) && !add(/*...*/) {
    if (notApplicable())
        return proceed(c);

    return proceed(getUpToDateCollection());
}

// matches Collection.contains(Object), ...
* around(Collection c, Object arg) : call(* Collection.*(*)) && target(c) && args(arg) 
            && !remove(/*...*/) && !add(/*...*/) {
    if (notApplicable())
        return proceed(c, arg);

    return proceed(getUpToDateCollection(), arg);
}

它有效,但它非常丑陋,我的建议的主体非常相似。所以我想“组合”它们;有效地为两个切入点编织了一个建议,就像这样:

* around(Object[] args): call(* Collection.*(..)) && args(arr) {...}`

这可能吗?我感觉不是,因为在其中一个切入点中我公开了参数(随后在建议中使用它),而在另一个切入点中没有参数,因此似乎不可能在封闭建议中绑定“潜在标识符” ......但我希望我忽略了一些事情,你也许能指出我正确的方向。谢谢!

4

2 回答 2

0

只是为了记录。
可以编写一个暴露参数的切入点,然后在不访问这些参数参数的建议中使用这个切入点。与其将切入点表达式立即写入通知定义,我总是更喜欢显式定义切入点,仅通过切入点的名称(和参数)从建议中引用它

于 2010-09-12T01:04:31.980 回答
0

我不知道为什么这么多年后这个问题在我的提要中以“新”的形式出现,但仍然没有答案,所以我将回答:

  • 您的假设是正确的,您不能使用args()它来绑定不存在的参数。
  • 如果你绝对想要一个通知体,你可以使用JoinPoint.getArgs(..),但它会很丑陋(如涉及循环和强制转换)并且可能比拥有两个切入点慢。如果做错了,太宽的切入点也可能匹配太多的连接点。
  • 我的建议——没有双关语的意思——实际上是将重复的代码分解为辅助方法,并从两个 AspectJ 建议中调用它们。如果您还想排除该部分,那么这些辅助方法可能还需要一个ProceedingJoinPoint参数才能调用它。proceed()但也要考虑可读性。它总是取决于你的具体情况。

如果您的代码实际上是一个小 SSCCE ,我可以以更具体的方式(使用方面代码)回答。

于 2017-05-29T03:48:16.263 回答