当切点在超类上但派生类覆盖时,如何避免两次命中切入点?
Posted
技术标签:
【中文标题】当切点在超类上但派生类覆盖时,如何避免两次命中切入点?【英文标题】:How to avoid hitting pointcut twice when the cut is on a superclass, but a derived class overrides? 【发布时间】:2012-08-31 00:10:50 【问题描述】:很难给它起一个简洁的标题。
无论如何,假设我有一个父类:
public class Shape
public Dimensions getDimensions()
// Does some generic stuff.
我有一个派生类,它覆盖了 getDimensions 方法:
public class Circle extends Shape
public Dimensions getDimensions()
// Does some stuff.
super.getDimensions();
当我在Shape.getDimensions
上创建带有切入点的切面时,在调用Circle.getDimensions
时会命中两次切入点:一次用于Circle.getDimensions
,然后一次用于调用super.getDimensions
。
切入点如下所示:@Pointcut("execution(* Shape.getDimensions(..))")
我在建议中添加了一个 hack 来检查声明类型的名称(使用 JoinPoint.getSignature().getDeclaringType().getName()
),但我觉得它很粗俗,感觉有点像 hack。我认为必须有更好的方法来做到这一点。
有吗?
如果格式不是很好,请见谅。第一次在这里问问题(我通常已经找到答案了)。
【问题讨论】:
【参考方案1】:可能您的意思是您的切入点使用Shape+.getDimensions()
(带有加号),否则它根本不会匹配Circle
。
无论如何,你可以像这样解决问题(我希望原生 AspectJ 语法对你来说没问题,我觉得它更清晰,更有表现力):
public aspect ShapeAspect
pointcut getDimensions() : execution(* Shape+.getDimensions());
pointcut getDimensionsNoSuper() : getDimensions() && !cflowbelow(getDimensions());
after() : getDimensionsNoSuper()
System.out.println(thisJoinPointStaticPart);
【讨论】:
效果很好,谢谢。我更习惯注释样式,但关键是 cflowbelow 调用。在试图弄清楚我是否可以将其浓缩成一个建议(无法弄清楚)的过程中,我发现了这个可爱的附录:eclipse.org/aspectj/doc/next/progguide/semantics-pointcuts.html 提前感谢您接受并支持我的回答。 ;-) 请做。 我显然需要 15 分才能这样做。我只有 11 个。相信我,我试过了! :( 其实execution
也会匹配超类方法,不管有没有+
@Sean:这就是为什么切入点有另一个条件过滤掉超类方法的执行。你试过了吗?以上是关于当切点在超类上但派生类覆盖时,如何避免两次命中切入点?的主要内容,如果未能解决你的问题,请参考以下文章