Я скопировал ваш код в проект AspectJ (там нет Spring или Spring AOP), чтобы протестировать его. Я нашел несколько проблем:
@Around("@annotation(MyAnnotation)")
не найдет аннотацию, поскольку не существует полностью определенного имени класса.
declare @method : void ItemRepository+.getById() : @MyAnnotation;
не соответствует сигнатуре вашего метода интерфейса Item getById(Long id)
.
MyAspects.execute(..)
необходимо выбросить Throwable
и, конечно, также вернуть что-то, например, результат joinPoint.proceed()
. Но, возможно, это было просто неаккуратное копирование и вставка.
После исправления этого, MCVE прекрасно работает:
Вспомогательные классы, компилирующие проект:
package de.scrum_master.app;
public class Item {}
package de.scrum_master.app;
public interface JpaRepository<P, Q> {}
package de.scrum_master.app;
import org.springframework.stereotype.Repository;
@Repository
public interface ItemRepository extends JpaRepository<Item, Long> {
Item getById(Long id);
}
package de.scrum_master.app;
public class ItemRepositoryImpl implements ItemRepository {
@Override
public Item getById(Long id) {
return new Item();
}
}
Маркерная аннотация:
package de.scrum_master.app;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {}
Применение драйвера:
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
ItemRepository repository = new ItemRepositoryImpl();
repository.getById(11L);
}
}
аспекты:
На тот случай, если вам интересно, почему я добавил execution(* *(..))
к pointcut, это потому, что я хотел исключить совпадающие call()
точек соединения, которые доступны в AspectJ, а не Spring AOP.
package de.scrum_master.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MyAspect {
@Around("@annotation(de.scrum_master.app.MyAnnotation) && execution(* *(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println(joinPoint);
return joinPoint.proceed();
}
}
package de.scrum_master.aspect;
import de.scrum_master.app.Item;
import de.scrum_master.app.ItemRepository;
import de.scrum_master.app.MyAnnotation;
public aspect AnnotationInheritor {
declare @method : Item ItemRepository+.getById(Long) : @MyAnnotation;
}
Журнал консоли:
execution(Item de.scrum_master.app.ItemRepositoryImpl.getById(Long))
Вуаля! Работает хорошо.
Если это не работает для вас, у вас есть другие проблемы, такие как (но не исключительно)
"автоматически сгенерированный ItemRepositoryImpl#getById
", который вы упомянули мимоходом. Когда бы и где бы он ни создавался в процессе сборки, он должен существовать до того, как к нему будет применен аспект. Для анализа мне понадобится MCVE на GitHub, хотя.
находится ли целевой код для включения аспекта в том же модуле Maven, что и код аспекта. Если это не так, вам нужно изменить настройки Maven.