Я использую 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.
Есть идеи, как это решить?
Вероятно, вы используете не AspectJ, а Spring AOP. Итак, есть несколько вещей, которые следует учитывать:
@Component
, а не с вещами, отличными от Spring. Для этого вам действительно понадобится AspectJ. Таким образом, ваши аспекты Spring AOP все равно ищут эту аннотацию.@Component
s, но они автоматически исключаются из объединения аспектов. В AspectJ вам потребуются особые меры предосторожности, чтобы исключить один аспект, переплетенный с другим, имеющим ту же аннотацию, что и обычный код приложения. Вам нужно будет учитывать это в ситуациях, когда вы комбинируете Spring AOP с полным AspectJ.Теперь, что касается вашего вопроса об АОП, вы не можете перехватывать точки соединения в аннотированном классе через @annotation()
pointcut, как вы уже заметили. Вместо этого вам нужно использовать @within()
, например:
@within(org.springframework.stereotype.Component)
Обратите внимание, что это перехватит все точки соединения в аннотированных классах, то есть в случае Spring AOP все выполнения методов. Он не будет перехватывать создание bean-компонента, если, как следует из вашего сообщения журнала, это ваша цель.
Осторожно: @EnableAspectJAutoProxy
для Spring AOP, @EnableLoadTimeWeaving
для AspectJ. Вы не хотите активировать оба одновременно, если хотите использовать только один тип инструмента АОП. Поэтому, пожалуйста, снова удалите @EnableLoadTimeWeaving
, иначе ваши аспекты могут быть сплетены дважды двумя разными инструментами. Пожалуйста, узнайте разницу между ними, прочитав руководство Spring. Что касается вашей новой проблемы, я не могу понять ее, не видя вашего кода. Возможно, вы хотите опубликовать MCVE в новом вопросе.
Эти две конфигурации
@EnableAspectJAutoProxy(proxyTargetClass = true) @EnableLoadTimeWeaving(aspectjWeaving = AspectJWeaving.ENABLED)
должны были включить мне AspectJ. Я проверил, что бины плетутся с CBLIB, так что это AspectJ. Вы правы, что@within
методы вызываются при каждом вызове метода, и это работает. С другой стороны, когда я хочу поймать bean-компонент послеContextRefreshedEvent
, проксированный bean-компонент с CGLIB не работает должным образом. Я хочу добавить к ним связанные поля Serenity (net.serenitybdd.core.Serenity.initialize(bean)). Вероятно, это другой компонент, над которым я хочу поработать позже.