Я работаю над приложением Vaadin и хочу использовать аспект @Around для перехвата вызова метода при нажатии кнопки Vaadin. В частности, я хотел бы регистрировать информацию о событии нажатия кнопки. Как я могу добиться этого, используя Spring AOP и совет @Around? Или это вообще возможно?
Мой текущий демонстрационный проект выглядит так:
AspectDemoApplication.java:
package com.example.aspectdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@SpringBootApplication
@EnableAspectJAutoProxy
public class AspectDemoApplication {
public static void main(String[] args) {
SpringApplication.run(AspectDemoApplication.class, args);
}
}
КликИнформация.java:
package com.example.aspectdemo.config;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Aspect
@Component
@Slf4j
public class ClickInformation {
@Around("execution(* com.vaadin.flow.component.ComponentEventListener+.onComponentEvent(..))")
public Object logClickInformation(ProceedingJoinPoint pjp) throws Throwable{
String method = pjp.getSignature().getName();
String targetClass = pjp.getTarget().getClass().getName();
String params = Arrays.toString(pjp.getArgs());
String msg = """
target: %s
method: %s
parameters: %s
""".formatted(targetClass, method, params);
log.info(msg);
return pjp.proceed();
}
}
MainView.java:
package com.example.aspectdemo.ui;
import com.vaadin.flow.component.ClickEvent;
import com.vaadin.flow.component.ComponentEventListener;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;
@Route("")
public class MainView extends VerticalLayout {
public MainView() {
initUI();
}
public void initUI () {
btnTest1 = new Button("Test1");
btnTest2 = new Button("Test2");
btnTest1.addClickListener(new ComponentEventListener<ClickEvent<Button>>() {
@Override
public void onComponentEvent(ClickEvent<Button> buttonClickEvent) {
System.out.println("Button Test1 clicked");
}
});
btnTest2.addClickListener(new ComponentEventListener<ClickEvent<Button>>() {
@Override
public void onComponentEvent(ClickEvent<Button> buttonClickEvent) {
System.out.println("Button Test2 clicked");
}
});
this.add(btnTest1, btnTest2);
}
public Button btnTest1;
public Button btnTest2;
}
Чего я пытаюсь добиться, так это записать информацию о вызове метода нажатия кнопки при каждом нажатии кнопки в представлении с помощью Aspect. Надеюсь, это прояснит ситуацию. Я что-то упустил или это просто невозможно? Заранее благодарны за Вашу помощь!
С наилучшими пожеланиями.
В частности, пожалуйста, поймите, что существует так много способов неправильно настроить свой аспект и целевой код, который будет сплетен с ним, что было бы чистой спекуляцией пытаться вам помочь. Такие вещи, как имена классов и пакетов, конфигурация Spring, аннотации и т. д. важны, т. е. нам нужны полные (!) аспекты, целевые классы и конфигурации. Думаю, у меня есть довольно хорошее представление о том, что может быть не так в вашем случае, но я ненавижу спекулировать.
Привет, я обновил свой вопрос примером проекта. Надеюсь, это прояснит ситуацию!
Подобный вопрос буквально задавался здесь уже десятки или сотни раз. Мой совет вам, как и вашим предшественникам, изучить некоторые примеры или документацию, прежде чем использовать новый инструмент.
@kriegaex, этот вопрос уже задавали сотни раз, не могли бы вы перечислить некоторые из этих вопросов?
Конечно. Вот лишь на некоторые из них, на которые я ответил сам: stackoverflow.com/a/64289370/1082681 , stackoverflow.com/a/50093552/108268 , stackoverflow.com/a/57456924/1082681 , stackoverflow.com/a/38158365/1082681 , stackoverflow.com/a/31629976/1082681. Есть еще места, откуда они пришли.




Spring AOP работает, как следует из названия и документально, только для bean-компонентов или компонентов, управляемых Spring (@Component, @Bean, @Service и т. д.). Ваши анонимные классы слушателей не управляются Spring. Следовательно, Spring AOP не может их перехватить. Либо убедитесь, что ваши целевые классы действительно управляются Spring, либо переключитесь на собственный AspectJ.
Добро пожаловать в СО. Пожалуйста, научитесь как задавать вопросы по SO и предоставьте минимальный, полный и проверяемый пример. Спасибо.