Aspectj:lambda表达式的切入点
我有一个正在迁移到
Java8的
Java6项目.我们使用aspectj来记录一些用户操作,比如按钮点击.
所以有听众这样: button.addClickListener(new Button.ClickListener() { @Override public void buttonClick(Button.ClickEvent clickEvent) { doSth(); } }); 和poincut: @Pointcut("execution(public void Button.ClickListener.buttonClick(Button.ClickEvent))") public void buttonClick() {}; 但是既然我们将使用Java8,那么听众将是这样的: button.addClickListener(clickEvent -> doSth()); 有没有办法编写aspectj切入点,以便它处理新的侦听器? 解决方法
我想问题是lambdas似乎并没有实际实现/覆盖任何具有相应名称的接口方法,而是创建一个匿名方法.看看这个例子:
虚拟按钮类,复制我们需要的Vaadin部分: package de.scrum_master.app; public class Button { private ClickListener listener; public void addClickListener(ClickListener listener) { this.listener = listener; } public void click() { System.out.println("Clicking button"); listener.buttonClick(new ClickEvent()); } public static class ClickEvent {} public static interface ClickListener { public void buttonClick(ClickEvent clickEvent); } } 司机申请: package de.scrum_master.app; public class Application { protected static void doSomething() {} public static void main(String[] args) { Button button = new Button(); button.addClickListener(new Button.ClickListener() { @Override public void buttonClick(Button.ClickEvent clickEvent) { doSomething(); } }); button.click(); button = new Button(); button.addClickListener(clickEvent -> doSomething()); button.click(); } } 如您所见,创建了两个按钮实例,一个具有经典的匿名类侦听器,另一个具有lambda侦听器.单击这两个按钮,因此控制台日志如下所示: Clicking button Clicking button 方面: package de.scrum_master.aspect; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class ButtonClickLogger { @Before("execution(public void *..Button.ClickListener.buttonClick(*..Button.ClickEvent))") public void logButtonClick(JoinPoint thisJoinPoint) { System.out.println("Caught button click: " + thisJoinPoint); } @Before("within(*..Application)") public void logAllInListener(JoinPoint thisJoinPoint) { System.out.println(" " + thisJoinPoint); } @Before("execution(void *..lambda*(*..Button.ClickEvent))") public void logButtonClickLambda(JoinPoint thisJoinPoint) { System.out.println("Caught button click (lambda): " + thisJoinPoint); } } 第一个建议使用类似于你的切入点.它只能拦截经典的侦听器声明. 第二个建议是用于调试目的,并记录驱动程序应用程序中的所有连接点,以显示这里发生了什么. 最后,但并非最不重要的是,第三个建议显示了拦截基于lambda的侦听器的解决方法,依赖于从调试输出获取的有关lambdas的Java编译器命名的知识.这不是很好,但目前它的工作原理.请注意,buttonClick(..)的lambda版本不是公共的,所以它只是void * .. lambda *,而不是public void * .. lambda *. 使用AspectJ的控制台输出: staticinitialization(de.scrum_master.app.Application.<clinit>) execution(void de.scrum_master.app.Application.main(String[])) call(de.scrum_master.app.Button()) call(de.scrum_master.app.Application.1()) staticinitialization(de.scrum_master.app.Application.1.<clinit>) preinitialization(de.scrum_master.app.Application.1()) initialization(de.scrum_master.app.Application.1()) initialization(de.scrum_master.app.Button.ClickListener()) execution(de.scrum_master.app.Application.1()) call(void de.scrum_master.app.Button.addClickListener(Button.ClickListener)) call(void de.scrum_master.app.Button.click()) Clicking button Caught button click: execution(void de.scrum_master.app.Application.1.buttonClick(Button.ClickEvent)) execution(void de.scrum_master.app.Application.1.buttonClick(Button.ClickEvent)) call(void de.scrum_master.app.Application.doSomething()) execution(void de.scrum_master.app.Application.doSomething()) call(de.scrum_master.app.Button()) call(void de.scrum_master.app.Button.addClickListener(Button.ClickListener)) call(void de.scrum_master.app.Button.click()) Clicking button execution(void de.scrum_master.app.Application.lambda$0(Button.ClickEvent)) Caught button click (lambda): execution(void de.scrum_master.app.Application.lambda$0(Button.ClickEvent)) call(void de.scrum_master.app.Application.doSomething()) execution(void de.scrum_master.app.Application.doSomething()) 更新:AspectJ现在有一个相应的Bugzilla issue.我刚刚创建了它.它还指出了最近对邮件列表的讨论. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 一种Java方法,只能由其自己的类或其他子类调用
- java – 有没有理由更喜欢数据挖掘项目的函数式编程?
- java – NamedEntityGraph – JPA / Hibernate抛出org.hibe
- java – 如何从Guice Injector获取所有单例实例?
- java-单例详解
- Java 使用POI生成带联动下拉框的excel表格实例代码
- Spring IO Platform简单介绍
- 在哪里可以获得与Java 8 jdk早期版本一起使用的tools.jar
- java – 计算方法调用栈大小来检查StackOverflowException
- java – 如何更改JOptionPane.showInputDialog中按钮的默认