Разница между указателями внутри и внутри кода в AspectJ - PullRequest
0 голосов
/ 06 мая 2019

Я новичок в аспектно-ориентированном программировании. В этом контексте я прошел через несколько указателей, в которых я нашел два указателя «внутри» и «внутри кода». Я не мог понять их разницу. Может кто-нибудь объяснить, пожалуйста, на простом примере?

Ответы [ 2 ]

2 голосов
/ 07 мая 2019

Ответ Нандора правильный, вы должны принять + поднять голос.Я просто хочу добавить 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() do.

1 голос
/ 06 мая 2019

Из Руководство по программированию AspectJ - Семантика языка - Pointcuts

within(TypePattern)
Выбирает каждую точку соединения, где исполняемый код определен в типе, соответствующем TypePattern.

withincode(MethodPattern)
Выбирает каждую точку соединения, где исполняемый код определен в методе, подпись которого соответствует MethodPattern .

С помощью within вы можете ограничиться только типом, поэтому без дополнительных ограничений он будет сопоставлять любые точки соединения внутри совпадающих типов. С другой стороны, используя withincode, вы можете использовать шаблон, который сужает возможные совпадающие точки соединения дальше, до уровня методов.

В конце страницы, на которую я ссылался, есть сводка EBNF о грамматике для шаблонов, используемых в документе.

...