2016-11-24 2 views
4

У меня есть следующий аспект:AspectJ - Избегайте срезы в называющей себя косвенно

public aspect MyAspect { 

before(String val): args(val, ..) && 
    call(public * execute(java.lang.String, ..)) { 
    // Do something 
    } 
} 

И следующие классы & B, A использует B:

class A() { 
public void execute(String a) { 
    // Do something... 
    B b = new B(); 
    b.execute(); 
} 
} 

class B { 
    public void execute(String a) { 
    // Do something 
    } 
} 

И у меня есть тестовый класс:

public class TestClass { 
    public static void main(String[] args) { 
    A a = new A(); 
    a.execute("someVal"); // I want the aspect to be called for the first execute only 
    B b = new B(); 
    b.execute("someVal");  
    } 
} 
  • В случае, если мы называем a.execute() Я не хочу, чтобы выполнить аспект, чтобы быть пойманным снова на Б.
  • С другой стороны, когда мы называем b.execute() непосредственно из теста я хочу, чтобы поймать аспект b.execute().

Как это можно достичь? Я попытался использовать cflowbelow (с отрицанием), но это не сработало.

---- редактировать ----

Чтобы быть более точным, давайте Явы FilterChain.doFilter (..) - фильтры могут вызывать другие фильтры. Я только хочу поймать первый вызов doFilter (я знаю, что это может быть сделано с использованием ThreadLocal в случае fiter, но фильтр - только пример).

Спасибо,

Lin

+0

Имейте попытку &&! Внутри (A)? – dreamcrash

+0

Нет, потому что я не хочу исключать A. Если тест был только a.execute (""), я хочу поймать этот вызов. – Lin

+0

Временное решение может быть: вы сохраняете имя метода в treeSet для проверки или нет, если вы уже перехватили этот метод до – dreamcrash

ответ

3

Это работает для меня:

pointcut intercept_call() : call(public * execute(java.lang.String, ..)); 


before(String val): intercept_call() && !cflowbelow(intercept_call()) && args(val, ..) 
{ 

    // do soemthing 
    } 
} 

Не знаю, если он делает то, что вы ищете.

+0

Спасибо, но я не хочу исключать A или B, я просто хочу исключить B в случае, если A уже был вызван. AFAIK, если я использую! Внутри (A) Я никогда не поймаю никаких вызовов из A ... – Lin

+0

Что-то вроде: &&! (Call (public * test.B.execute (java.lang.String)) \t \t \t && in (A)) – dreamcrash

+0

Проблема в том, что мой код является общим - я поймаю любую функцию, определенную как «execute (String)», поэтому в моем примере я использовал классы A и B, но в Я не знаю реальных классов и кода, который будет кодировать выполнение. – Lin

Смежные вопросы