AspectJ Pointcut не работает с аннотациями с Element.TYPE, такими как @Component

Я использую AspectJ и пытаюсь указать аннотацию @Component.

@Pointcut("@annotation(org.springframework.stereotype.Component)")
   public void bean() {
}

@Before("bean()")
public void beforeBeanCreation(JoinPoint jp) {
    System.out.println("Works!");
}

Моя конфигурация выглядит следующим образом:

@Configuration
@ComponentScan({"com.app.pl"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableLoadTimeWeaving(aspectjWeaving = AspectJWeaving.ENABLED)
public class AppConfiguration{

}

Все работает, когда я хочу указать на аннотацию с помощью ElementType.METHOD или на компонент с определенным именем. Но Pointcut в аннотации с ElementType.TYPE не работает. Я предполагаю, что проблема связана с аннотациями, которые читаются раньше, чем прокси-сервер AspectJ.

Есть идеи, как это решить?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
0
1 812
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вероятно, вы используете не AspectJ, а Spring AOP. Итак, есть несколько вещей, которые следует учитывать:

  • Обычно аспекты Spring AOP в любом случае работают с @Component, а не с вещами, отличными от Spring. Для этого вам действительно понадобится AspectJ. Таким образом, ваши аспекты Spring AOP все равно ищут эту аннотацию.
  • Аспекты Spring AOP тоже должны быть @Components, но они автоматически исключаются из объединения аспектов. В AspectJ вам потребуются особые меры предосторожности, чтобы исключить один аспект, переплетенный с другим, имеющим ту же аннотацию, что и обычный код приложения. Вам нужно будет учитывать это в ситуациях, когда вы комбинируете Spring AOP с полным AspectJ.

Теперь, что касается вашего вопроса об АОП, вы не можете перехватывать точки соединения в аннотированном классе через @annotation() pointcut, как вы уже заметили. Вместо этого вам нужно использовать @within(), например:

@within(org.springframework.stereotype.Component)

Обратите внимание, что это перехватит все точки соединения в аннотированных классах, то есть в случае Spring AOP все выполнения методов. Он не будет перехватывать создание bean-компонента, если, как следует из вашего сообщения журнала, это ваша цель.

Эти две конфигурации @EnableAspectJAutoProxy(proxyTargetClass = true) @EnableLoadTimeWeaving(aspectjWeaving = AspectJWeaving.ENABLED) должны были включить мне AspectJ. Я проверил, что бины плетутся с CBLIB, так что это AspectJ. Вы правы, что @within методы вызываются при каждом вызове метода, и это работает. С другой стороны, когда я хочу поймать bean-компонент после ContextRefreshedEvent, проксированный bean-компонент с CGLIB не работает должным образом. Я хочу добавить к ним связанные поля Serenity (net.serenitybdd.core.Serenity.initialize(bean)). Вероятно, это другой компонент, над которым я хочу поработать позже.

Adriano 31.05.2019 08:02

Осторожно: @EnableAspectJAutoProxy для Spring AOP, @EnableLoadTimeWeaving для AspectJ. Вы не хотите активировать оба одновременно, если хотите использовать только один тип инструмента АОП. Поэтому, пожалуйста, снова удалите @EnableLoadTimeWeaving, иначе ваши аспекты могут быть сплетены дважды двумя разными инструментами. Пожалуйста, узнайте разницу между ними, прочитав руководство Spring. Что касается вашей новой проблемы, я не могу понять ее, не видя вашего кода. Возможно, вы хотите опубликовать MCVE в новом вопросе.

kriegaex 31.05.2019 12:13

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