AspectJ中内部代码指示符与内部代码指示符之间的区别

时间:2019-05-06 04:37:34

标签: aop aspectj aspect

我是面向方面编程的新手。在这种情况下,我已经浏览了几个指示符,在其中找到了两个指示符“ within”和“ withincode”。我不明白他们的区别。任何人都可以用一个简单的例子来解释吗?

2 个答案:

答案 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摘要。