Java 在ForkJoinPool方法上应用方面(非spring托管bean)

Java 在ForkJoinPool方法上应用方面(非spring托管bean),java,spring,spring-aop,mdc,forkjoinpool,Java,Spring,Spring Aop,Mdc,Forkjoinpool,我想将MDC上下文映射复制并设置为spring应用程序中由ForkJoinPool管理的线程。不幸的是,我无法在execute方法上添加aop,因为ForkJoinPool是非托管Springbean。 我也不能在ForkJoinTask上应用aop。 您知道如何在非bean类上应用aop吗?或者如何将MDC上下文映射复制到ForkJoinPool @Slf4j @Component @Aspect public class ForkJoinTaskAspect { @Around(&

我想将MDC上下文映射复制并设置为spring应用程序中由ForkJoinPool管理的线程。不幸的是,我无法在execute方法上添加aop,因为ForkJoinPool是非托管Springbean。 我也不能在ForkJoinTask上应用aop。 您知道如何在非bean类上应用aop吗?或者如何将MDC上下文映射复制到ForkJoinPool

@Slf4j
@Component
@Aspect
public class ForkJoinTaskAspect {

    @Around("execution(* java.util.concurrent.ForkJoinPool.execute(..))")
    public Object executionAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
        log.debug("ForkJoinTaskAspect:: Before invoking execute() method");
        Map<String, String> contextMap = MDC.getCopyOfContextMap();
        Object value = null;
        try {
            MDC.setContextMap(contextMap);
            value = proceedingJoinPoint.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        finally {
            MDC.clear();
        }
        log.debug("ForkJoinTaskAspect:: After invoking execute() method. Return value=" + value);
        return value;
    }
}
@Slf4j
@组成部分
@面貌
公共类ForkTaskAspect{
@大约(“execution(*java.util.concurrent.ForkJoinPool.execute(..)”)
建议周围的公共对象执行(ProceedingJoinPoint ProceedingJoinPoint){
debug(“ForkJoinTaskAspect::在调用execute()方法之前”);
Map contextMap=MDC.getCopyOfContextMap();
对象值=空;
试一试{
setContextMap(contextMap);
value=proceedingJoinPoint.procedure();
}捕获(可丢弃的e){
e、 printStackTrace();
}
最后{
MDC.clear();
}
debug(“ForkJoinTaskAspect::调用execute()方法后。返回值=“+value”);
返回值;
}
}
用户已经给了您正确的线索,您只能使用本机AspectJ建议不是SpringBean的类

在这种情况下,您希望在引导类路径上编织成一个JRE类,这在AspectJ中是不容易实现的,因此您的任务更加复杂。因此,除非您想做一些相当丑陋的事情,比如二进制JRE类编织,并将编织好的JRE类放在引导类路径上,否则我建议您使用
call()
而不是
execution()
编织到您的应用程序目标类中。这意味着您不会编织被调用方类
ForkJoinPool
,而是编织所有调用类。下面是一个小例子:

package de.scrum\u master.app;
导入java.util.concurrent.ForkJoinPool;
公共类应用程序{
公共静态void main(字符串[]args)引发InterruptedException{
ForkJoinPool.commonPool().execute(()->{
System.out.println(“在ForkJoinPool中执行的任务”);
});
睡眠(100);
}
}
package de.scrum\u master.aspect;
导入java.util.Map;
导入org.aspectj.lang.ProceedingJoinPoint;
导入org.aspectj.lang.annotation.Around;
导入org.aspectj.lang.annotation.Aspect;
导入org.slf4j.MDC;
@面貌
公共类ForkTaskAspect{
@大约(“call(*java.util.concurrent.ForkJoinPool.execute(..)”)
建议周围的公共对象执行(ProceedingJoinPoint ProceedingJoinPoint){
System.out.println(“在”+处理接合点之前);
Map contextMap=MDC.getCopyOfContextMap();
对象值=空;
试一试{
setContextMap(contextMap);
value=proceedingJoinPoint.procedure();
}捕获(可丢弃的e){
e、 printStackTrace();
}最后{
MDC.clear();
}
System.out.println(“在”+处理接合点之后);
返回值;
}
}
META-INF/aop.xml文件将是:


控制台日志将是:

[AppClassLoader@18b4aac2]weaveinfo连接点“方法调用(void java.util.concurrent.ForkJoinPool.execute(java.lang.Runnable)),类型为“de.scrum_master.app.Application”(Application.java:7),由“de.scrum_master.aspect.ForkJoinTaskAspect”(ForkJoinTaskAspect.aj)的建议
调用前(void java.util.concurrent.ForkJoinPool.execute(Runnable))
调用后(void java.util.concurrent.ForkJoinPool.execute(Runnable))
在ForkJoinPool中执行的任务

您可以在官方文档中使用AspectJ。很好的解释。我没有想到这是一个JRE类