我是面向方面编程的新手。在这种情况下,我已经浏览了几个指示符,在其中找到了两个指示符“ within”和“ withincode”。我不明白他们的区别。任何人都可以用一个简单的例子来解释吗?
答案 0 :(得分:2)
南多尔的答案是正确的,您应该接受+赞成。我只想添加一个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]
如您所见,与within()
相比,withincode()
与超级连接点集匹配。当然,您可以通过&&
将两个切入点与其他切入点组合在一起,以进一步缩小匹配的连接点集,或者通过||
对其进行扩展。当然,也可以通过!
进行排除。
请进一步注意,withincode()
与目标方法内部发生的情况匹配,但与方法执行本身不匹配。在这方面,它类似于cflowbelow()
,但与cflow()
和cflowbelow()
一样,从那里调用的方法之外的任何东西都不匹配。
答案 1 :(得分:1)
从AspectJ Programming Guide - Language Semantics - Pointcuts
within(TypePattern)
按TypePattern匹配的类型挑选出定义执行代码的每个连接点。
withincode(MethodPattern)
在签名与MethodPattern匹配的方法中挑选出定义执行代码的每个连接点。
使用within
,您只能限制一个类型,因此没有其他限制,它将匹配匹配类型内的所有连接点。另一方面,使用withincode
,可以使用一种模式,将可能的匹配连接点进一步缩小到方法级别。
在我链接的页面末尾,有关于文档中使用的模式的语法的EBNF摘要。