2009-01-08 25 views
0

在我的方面,我通过建议某些方法调用java.util.Set,特别是add(Object)remove(Object),来跟踪某些集合的更改。由于这些更改未反映在集合本身中,所以Set.contains(Object)Set.size()的调用返回错误的结果。使用连接点调用(* *。*(..)),如果可用,我可以将参数公开给建议吗?

因此,我想截取所有方法调用的集合实例(除addremove),并将调用转发给我最新的集合。

当然我也定义了两个建议,使用不同的切入点,是这样的:

// 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) {...}` 

这是可能的吗?我感觉它不是,因为在一个切入点中我公开了这个参数(并且随后在建议中使用它),另一个没有参数,所以似乎不可能在封装的通知中绑定“潜在标识符” ......但我希望我忽略了一些事情,并且可能能够指引我朝着正确的方向前进。谢谢!

回答

0

只是备案。
可能写一个暴露参数的切入点,然后在不访问这些参数参数的通知中使用此切入点。而不是直接写入建议定义的切入点表达式,我宁愿明确定义切入点,从切入点的名称(和参数)引用它的建议

+0

我不明白这个答案。 – kriegaex 2017-05-29 03:41:50

0

我不知道为什么这个问题有在我的饲料为“新”经过这么多年的弹出,但它仍然没有答案,所以我会回答:

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

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

相关问题