Можно ли использовать AOP для события нажатия кнопки в Vaadin?

Я работаю над приложением 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. Надеюсь, это прояснит ситуацию. Я что-то упустил или это просто невозможно? Заранее благодарны за Вашу помощь!

С наилучшими пожеланиями.

Добро пожаловать в СО. Пожалуйста, научитесь как задавать вопросы по SO и предоставьте минимальный, полный и проверяемый пример. Спасибо.

kriegaex 28.02.2024 01:19

В частности, пожалуйста, поймите, что существует так много способов неправильно настроить свой аспект и целевой код, который будет сплетен с ним, что было бы чистой спекуляцией пытаться вам помочь. Такие вещи, как имена классов и пакетов, конфигурация Spring, аннотации и т. д. важны, т. е. нам нужны полные (!) аспекты, целевые классы и конфигурации. Думаю, у меня есть довольно хорошее представление о том, что может быть не так в вашем случае, но я ненавижу спекулировать.

kriegaex 28.02.2024 01:24

Привет, я обновил свой вопрос примером проекта. Надеюсь, это прояснит ситуацию!

Lukas 28.02.2024 08:04

Подобный вопрос буквально задавался здесь уже десятки или сотни раз. Мой совет вам, как и вашим предшественникам, изучить некоторые примеры или документацию, прежде чем использовать новый инструмент.

kriegaex 01.03.2024 14:18

@kriegaex, этот вопрос уже задавали сотни раз, не могли бы вы перечислить некоторые из этих вопросов?

Dario Viva 08.03.2024 00:49

Конечно. Вот лишь на некоторые из них, на которые я ответил сам: 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. Есть еще места, откуда они пришли.

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

Ответы 1

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

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

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