Java 为通过lambda表达式调用的Runnable.run方法执行@Before和@After方面
描述 如何为Runnable.run方法创建切入点,以便在java 8 lambda表达式中调用@Before和@After方面Java 为通过lambda表达式调用的Runnable.run方法执行@Before和@After方面,java,spring,lambda,aop,Java,Spring,Lambda,Aop,描述 如何为Runnable.run方法创建切入点,以便在java 8 lambda表达式中调用@Before和@After方面 为Runnable.run方法创建切入点 在步骤1中为切入点创建@Before方面。-->先打印后打印 在步骤1中为切入点创建@Aefore方面。-->可运行后打印 当在第行下方调用时 executor.runAsync(() -> { System.out.println("Runnable invoked"); } ) 预期产出: Before runn
executor.runAsync(() ->
{ System.out.println("Runnable invoked"); }
)
预期产出:
Before runnable
Runnable invoked
After runnable
此问题的解决方案不起作用
@大约(“执行(void com.test..lambda*(..)
这将适用于所有lambda表达式…我只想对Runnable.run方法进行限制。您不能,因为执行的lambda方法是静态的,也就是说,您甚至不能检查类似于
thisJoinPoint.getTarget()instanceof Runnable的内容,因为目标为null。对于匿名子类,这将起作用
也就是说,在对我的问题采取措施之前,你无法真正解决这个问题
更新:我为您找到了一个解决方案。这不太好,但至少在AspectJ更好地支持lambdas之前,它是有效的。不过,您需要根据调用相关runnable的方法对其进行调整:
驱动程序应用程序:
package de.scrum\u master.app;
导入java.util.concurrent.CompletableFuture;
导入java.util.concurrent.ExecutionException;
导入静态java.util.concurrent.TimeUnit.millizes;
公共类应用程序{
公共静态void main(字符串[]args)引发InterruptedException、ExecutionException{
CompletableFuture=CompletableFuture.runAsync(()->{
试一试{
毫秒。睡眠(100);
}捕捉(中断异常e){
抛出新的非法状态异常(e);
}
System.out.println(“独立线程lambda”);
});
CompletableFuture-future2=CompletableFuture.runAsync(newrunnable()){
@凌驾
公开募捐{
试一试{
毫秒。睡眠(100);
}捕捉(中断异常e){
抛出新的非法状态异常(e);
}
System.out.println(“独立线程匿名运行”);
}
});
System.out.println(“主线程”);
future.get();
未来2.获取();
}
}
方面:
package de.scrum\u master.aspect;
导入org.aspectj.lang.JoinPoint;
导入org.aspectj.lang.annotation.After;
导入org.aspectj.lang.annotation.Aspect;
导入org.aspectj.lang.annotation.Before;
导入org.aspectj.lang.annotation.Pointcut;
@面貌
公共类异步运行拦截器{
私有静态最终字符串类\u ASYNC\u RUN=“java.util.concurrent.CompletableFuture$AsyncRun”;
私有静态最终字符串方法\u RUN=“RUN”;
@切入点(“执行(void*(..)&&&&!在(de.scrum_master.aspect.AsyncRunInterceptor)和&if()中)
公共静态布尔值isAsyncRun(){
最终StackTraceElement[]stackTrace=新异常().getStackTrace();
if(stackTrace.length<3)
返回false;
最终StackTraceElement StackTraceElement=stackTrace[2];
返回
StackTraceeElement.getClassName()=类异步运行
&&StackTraceeElement.getMethodName()=方法\u运行;
}
@在(“isAsyncRun()”)之前
AsyncRun之前的公共无效(JoinPoint thisJoinPoint){
System.out.println(“+thisJoinPoint”之前的“[”+线程.currentThread().getId()+”);
}
@之后(“isAsyncRun()”)
异步运行后公共无效(JoinPoint thisJoinPoint){
System.out.println(“+thisJoinPoint”之后的“[”+线程.currentThread().getId()+”);
}
}
控制台日志:
主线程
[10] 执行前(void de.scrum\u master.app.Application.lambda$0())
[11] 执行前(void de.scrum\u master.app.Application.1.run())
分离螺纹λ
独立线程匿名可运行
[11] 执行后(void de.scrum\u master.app.Application.1.run())
[10] 执行后(void de.scrum_master.app.Application.lambda$0())
非常感谢您的快速回复。嗯,您还没有接受答案。答案是正确的。您有任何后续问题吗?此外,我刚刚更新了它,向您展示了如何解决此问题。上述解决方案将起作用…但问题是..thisJoinPoint.getTarget()仍然为空:(当然是。它有什么问题?此解决方案不需要它。代码完全符合您在问题中的要求。您是正确的。上述问题的解决方法是正确的。但我也在我的项目中寻找目标。)