AspectJ 中 within 和 withincode 指示符之间的区别
Difference between within and withincode designators in AspectJ
我是面向方面编程的新手。在这种情况下,我一直在研究一些指示符,其中我发现了两个指示符 "within" 和 "withincode"。我无法理解他们的区别。谁能用一个简单的例子解释一下?
来自AspectJ Programming Guide - Language Semantics - Pointcuts
within(TypePattern)
Picks out each join point where the executing code is defined in a type matched by TypePattern.
withincode(MethodPattern)
Picks out each join point where the executing code is defined in a method whose signature matches MethodPattern.
使用within
,您只能限制为一种类型,因此在没有进一步限制的情况下,它将匹配匹配类型内的任何连接点。另一方面,使用 withincode
,您可以使用一种模式将可能的匹配连接点进一步缩小到方法级别。
在我链接的页面末尾,有一个关于文档中使用的模式语法的 EBNF 摘要。
Nándor 的回答是正确的,你应该采纳+点赞。我只想添加一个 MCVE,一个简单的例子来说明他刚才解释得很好。我这样做是为了将来可能会发现这个问题的其他用户的利益,以帮助他们更好地理解这里理论上描述的内容。
驱动申请:
package de.scrum_master.app;
public class Application {
private int id;
private String name;
public Application(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Application[id=" + id + ", name=" + name + "]";
}
public void printName() {
System.out.println(this);
}
public static void main(String[] args) {
new Application(11, "My application").printName();
}
}
看点:
package de.scrum_master.aspect;
import de.scrum_master.app.Application;
public aspect WithinVsWithincodeAspect {
before() : withincode(* Application.printName()) {
System.out.println("[withincode] " + thisJoinPoint);
}
before() : within(Application) {
System.out.println("[within] " + thisJoinPoint);
}
}
控制台日志:
[within] staticinitialization(de.scrum_master.app.Application.<clinit>)
[within] execution(void de.scrum_master.app.Application.main(String[]))
[within] call(de.scrum_master.app.Application(int, String))
[within] preinitialization(de.scrum_master.app.Application(int, String))
[within] initialization(de.scrum_master.app.Application(int, String))
[within] execution(de.scrum_master.app.Application(int, String))
[within] set(int de.scrum_master.app.Application.id)
[within] set(String de.scrum_master.app.Application.name)
[within] call(void de.scrum_master.app.Application.printName())
[within] execution(void de.scrum_master.app.Application.printName())
[withincode] get(PrintStream java.lang.System.out)
[within] get(PrintStream java.lang.System.out)
[withincode] call(void java.io.PrintStream.println(Object))
[within] call(void java.io.PrintStream.println(Object))
[within] execution(String de.scrum_master.app.Application.toString())
[within] call(java.lang.StringBuilder(String))
[within] get(int de.scrum_master.app.Application.id)
[within] call(StringBuilder java.lang.StringBuilder.append(int))
[within] call(StringBuilder java.lang.StringBuilder.append(String))
[within] get(String de.scrum_master.app.Application.name)
[within] call(StringBuilder java.lang.StringBuilder.append(String))
[within] call(StringBuilder java.lang.StringBuilder.append(String))
[within] call(String java.lang.StringBuilder.toString())
Application[id=11, name=My application]
如您所见,与 withincode()
相比,within()
匹配 super-set 个连接点。当然,您可以通过 &&
将两个切入点与其他切入点组合,以进一步缩小匹配的连接点集或通过 ||
扩展它。当然,也可以通过 !
排除。
请进一步注意 withincode()
匹配目标方法内部发生的事情,而不是方法执行本身。在这方面,它类似于 cflowbelow()
,但它不会匹配从那里调用的方法之外的任何内容,如 cflow()
和 cflowbelow()
那样。
我是面向方面编程的新手。在这种情况下,我一直在研究一些指示符,其中我发现了两个指示符 "within" 和 "withincode"。我无法理解他们的区别。谁能用一个简单的例子解释一下?
来自AspectJ Programming Guide - Language Semantics - Pointcuts
within(TypePattern)
Picks out each join point where the executing code is defined in a type matched by TypePattern.
withincode(MethodPattern)
Picks out each join point where the executing code is defined in a method whose signature matches MethodPattern.
使用within
,您只能限制为一种类型,因此在没有进一步限制的情况下,它将匹配匹配类型内的任何连接点。另一方面,使用 withincode
,您可以使用一种模式将可能的匹配连接点进一步缩小到方法级别。
在我链接的页面末尾,有一个关于文档中使用的模式语法的 EBNF 摘要。
Nándor 的回答是正确的,你应该采纳+点赞。我只想添加一个 MCVE,一个简单的例子来说明他刚才解释得很好。我这样做是为了将来可能会发现这个问题的其他用户的利益,以帮助他们更好地理解这里理论上描述的内容。
驱动申请:
package de.scrum_master.app;
public class Application {
private int id;
private String name;
public Application(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Application[id=" + id + ", name=" + name + "]";
}
public void printName() {
System.out.println(this);
}
public static void main(String[] args) {
new Application(11, "My application").printName();
}
}
看点:
package de.scrum_master.aspect;
import de.scrum_master.app.Application;
public aspect WithinVsWithincodeAspect {
before() : withincode(* Application.printName()) {
System.out.println("[withincode] " + thisJoinPoint);
}
before() : within(Application) {
System.out.println("[within] " + thisJoinPoint);
}
}
控制台日志:
[within] staticinitialization(de.scrum_master.app.Application.<clinit>)
[within] execution(void de.scrum_master.app.Application.main(String[]))
[within] call(de.scrum_master.app.Application(int, String))
[within] preinitialization(de.scrum_master.app.Application(int, String))
[within] initialization(de.scrum_master.app.Application(int, String))
[within] execution(de.scrum_master.app.Application(int, String))
[within] set(int de.scrum_master.app.Application.id)
[within] set(String de.scrum_master.app.Application.name)
[within] call(void de.scrum_master.app.Application.printName())
[within] execution(void de.scrum_master.app.Application.printName())
[withincode] get(PrintStream java.lang.System.out)
[within] get(PrintStream java.lang.System.out)
[withincode] call(void java.io.PrintStream.println(Object))
[within] call(void java.io.PrintStream.println(Object))
[within] execution(String de.scrum_master.app.Application.toString())
[within] call(java.lang.StringBuilder(String))
[within] get(int de.scrum_master.app.Application.id)
[within] call(StringBuilder java.lang.StringBuilder.append(int))
[within] call(StringBuilder java.lang.StringBuilder.append(String))
[within] get(String de.scrum_master.app.Application.name)
[within] call(StringBuilder java.lang.StringBuilder.append(String))
[within] call(StringBuilder java.lang.StringBuilder.append(String))
[within] call(String java.lang.StringBuilder.toString())
Application[id=11, name=My application]
如您所见,与 withincode()
相比,within()
匹配 super-set 个连接点。当然,您可以通过 &&
将两个切入点与其他切入点组合,以进一步缩小匹配的连接点集或通过 ||
扩展它。当然,也可以通过 !
排除。
请进一步注意 withincode()
匹配目标方法内部发生的事情,而不是方法执行本身。在这方面,它类似于 cflowbelow()
,但它不会匹配从那里调用的方法之外的任何内容,如 cflow()
和 cflowbelow()
那样。