AspectJ - не может переопределить pointcut - типы параметров не совпадают

У меня есть абстрактный аспект, как это:

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);
    }
}

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

public abstract aspect FooAspect extends GenericAspect<Foo> {

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

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

невозможно переопределить pointcut. GenericAspect.callMethod(java.lang.Object[]) с помощью pointcut FooAspect.callMethod(java.lang.Object[]) не совпадает

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

1 ответ

Решение

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

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

Приложение для водителя:

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();
  }
}

Консольный журнал:

de.scrum_master.app.Foo@511d50c0

Обратите внимание, что аспект включается, в противном случае null будет напечатан здесь.

Другие вопросы по тегам