2017-02-12 42 views
0

У меня есть абстрактный аспект, как это:AspectJ - не может переопределить срез точек - типы параметров не совпадают

public abstract aspect GenericAspect<T> { 

    public abstract T createT(Object[] args); 

    abstract pointcut callMethod(Object[] args); 

    T around(Object[] args) : callMethod(args) { 
     return createT(args); 
    } 
} 

И я хотел бы расширить этот аспект еще один абстрактный аспект, который переопределяет только абстрактный срез точек. Как в следующем примере (где Foo является интерфейсом):

public abstract aspect FooAspect extends GenericAspect<Foo> { 

    pointcut callMethod(Object[] args): 
     call(Foo *.*(..)) && args(args); 
} 

Но у меня есть эта ошибка компиляции:

can't override pointcut GenericAspect.callMethod(java.lang.Object[]) with pointcut FooAspect.callMethod(java.lang.Object[]) parameter don't match

Как я могу решить эту проблему?

ответ

1

Я не знаю точно, почему ваш пример не работает, возможно, в AspectJ есть небольшая ошибка, или вы только что сделали ложные предположения относительно того, что возможно с AspectJ в сочетании с дженериками и абстрактными pointcuts. Я предлагаю вам задать тот же вопрос на AspectJ users mailing list.

В то же время, было бы хорошо, если бы вы это сделали, слегка изменив синтаксис и переместив привязку args() в совет, а не в pointcut?

приложение Driver:

package de.scrum_master.app; 

public class Application { 
    public static void main(String[] args) { 
    System.out.println(new Application().createFoo()); 
    } 

    public Foo createFoo(Object... args) { 
    return null; 
    } 
} 

Вспомогательный класс:

package de.scrum_master.app; 

public class Foo {} 

аспекты:

package de.scrum_master.aspect; 

public abstract aspect GenericAspect<T> { 
    public abstract T createT(Object[] args); 

    abstract pointcut callMethod(); 

    T around(Object[] args): callMethod() && args(args) { 
    return createT(args); 
    } 
} 
package de.scrum_master.aspect; 

import de.scrum_master.app.Foo; 

public abstract aspect FooAspect extends GenericAspect<Foo> { 
    pointcut callMethod(): 
    call(Foo *(..)); 
} 
package de.scrum_master.aspect; 

import de.scrum_master.app.Foo; 

public aspect ConcreteFooAspect extends FooAspect { 
    @Override 
    public Foo createT(Object[] args) { 
    return new Foo(); 
    } 
} 

журнала консоли:

[email protected] 

Пожалуйста, обратите внимание, что аспект умирает, иначе null будет напечатан здесь.

+0

Спасибо, это сработало для меня. Другой возможный вариант - извлечь аргументы из совета вокруг с помощью 'Object [] args = thisJoinPoint.getArgs();' – EstevaoLuis

+0

Ну, но тогда он становится уродливым, потому что вам нужно перебирать 'Object []', возвращенный 'getArgs' , В вашем примере вы получите свой собственный 'Object []' в качестве первого параметра метода с помощью метода Object []Args = (Object []) thisJoinPoint.getArgs() [0]; '. Я предпочитаю более безопасное решение без литья. Это также имеет преимущество ограничения соответствия pointcut методам, у которых действительно есть подпись с одним параметром 'Object []'. Не использовать 'args()', а просто 'getArgs()' означает if-else, итерацию, отливку и много байт-кодов в ненужных местах. – kriegaex