I’m working on a Vaadin application, and I want to use an @Around aspect to intercept the method call when a Vaadin button is clicked. Specifically, I’d like to log information about the button click event. How can I achieve this using Spring AOP and the @Around advice? Or is this even possible?
My current demo project looks like this:
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);
}
}
ClickInformation.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;
}
What I'm trying to achieve is to log information of the button click method call of every button click in the view using Aspect. I hope this makes it more clear.Am I missing something or is it just not possible? Thanks for your help in advance!
Best regards.
Spring AOP works, as implied by the name and documented, only for Spring-managed beans or components (@Component
, @Bean
, @Service
etc.). Your anonymous listener classes are not spring-managed. Hence, Spring AOP cannot intercept them. Either make sure your target classes are in fact Spring-managed or switch to native AspectJ.