Spring AOP LTW 不起作用,编织不会发生

Spring AOP LTW doesn't work, weaving doesn't happening

提问人:Sergejs Jevstigņejevs 提问时间:2/24/2023 更新时间:2/25/2023 访问量:127

问:

我正在创建简单的实验程序,它使用 LTW 将 aspect 编织到类中,但是不会发生 aspect 加载时间编织。您可以在 GitHub 中检查和使用代码,我稍后将对此进行介绍。我正在使用 Java 17 和 IntelliJ IDE。

使用方面:


@Aspect
@Component
public class MonitoringAspect {

    @Pointcut("execution(* com.sj.utilities.Watch.*(..))")
    public void monitoringOperation(){}

    @Around("monitoringOperation()")
    public Object aroundAdvice(ProceedingJoinPoint pjp)
            throws Throwable {
        System.out.println("Before " + pjp.getSignature() + " execution!");

        long startTime = System.nanoTime();
        Object retVal = pjp.proceed();
        long endTime = System.nanoTime();
        long executingTime = endTime - startTime;
        System.out.println("Method's execution time:\n"
                + "\t" + executingTime + " ns\n"
                + "\t" + (executingTime / 1000) + " μs\n"
                + "\t" + (executingTime / 1000000) + " ms\n"
                + "\t" + (executingTime / 1000000000) + " s");
        System.out.println("After " + pjp.getSignature() + " execution!");

        return retVal;
    }

}

我试图删除@Component,因为不需要方面 be,但它什么也没改变。

方面建议是 Watch 类的简单方法睡眠,实现了 FictiveWatch 接口(接口仅供 Spring 使用 JDK 动态代理使用)。

创建的 Java 注解配置:

@Configuration
//@EnableAspectJAutoProxy
@EnableLoadTimeWeaving(aspectjWeaving = AspectJWeaving.ENABLED)
@ComponentScan("com.sj")
public class AOPConfig implements LoadTimeWeavingConfigurer {

    @Override
    public LoadTimeWeaver getLoadTimeWeaver() {
        return new InstrumentationLoadTimeWeaver();
    }

    @Bean
    public InstrumentationLoadTimeWeaver loadTimeWeaver()  throws Throwable {
        return new InstrumentationLoadTimeWeaver();
    }

}

以及 xml 配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans <!-- namespaces ...-->

    <!-- this switches on the load-time weaving -->
    <context:load-time-weaver
        weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>

    <!-- this switches on the spring aop autoproxy -->
    <!--<aop:aspectj-autoproxy/>-->

    <!-- a service object; we will be profiling its methods -->
    <bean id="watch"
          class="com.sj.utilities.Watch"/>
    <bean id="monitoringAspect"
          class="com.sj.aspects.MonitoringAspect"/>

</beans>

要使用编织方面,我使用这个 META-INF/aop.xml 文件:

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
    <weaver
            options="-verbose -showWeaveInfo">
        <!-- only weave classes in our application-specific packages -->
        <include within="com.sj..*"/>
    </weaver>
    <aspects>
        <!-- weave in just this aspect -->
        <aspect name="com.sj.aspects.MonitoringAspect"/>
    </aspects>
</aspectj>

驱动程序类:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        //Check used JVM arguments
        System.out.println(ManagementFactory.getRuntimeMXBean().getInputArguments());

        //Java class LTW config
        //ApplicationContext context = new AnnotationConfigApplicationContext(AOPConfig.class);

        //XML LTW config
        ApplicationContext context = new ClassPathXmlApplicationContext("config/aop-xml-conf.xml");
        Watch watch = context.getBean(Watch.class);
        watch.sleeping(3000);
    }
}

在驱动程序类中,我使用 AnnotationConfig 或 XMLConfig 来使用 LTW,但未发生编织,因此未应用横切功能。以及我打印 JVM 参数使用的参数。

在使用 AnnotationConfig 或 XMLConfig 时,我唯一看到的是我使用的 JVM 参数:

[--add-opens=java.base/java.lang=ALL-UNNAMED, -Dspring.aop.proxy-target-class=false, -Dorg.aspectj.weaver.loadtime.configuration=trace, -Dorg.aspectj.weaver.loadtime.verbose=true, -javaagent:E:\intelliJIdea_dir\IntelliJ IDEA Community Edition 2022.2.1\lib\idea_rt.jar=55606:E:\intelliJIdea_dir\IntelliJ IDEA Community Edition 2022.2.1\bin, -Dfile.encoding=UTF-8]

以及 Watch睡眠方法的结果:

Slept 3000 ms

为什么没有编织,编写代码的哪一部分是不对的?根据 LTW 的 Spring 文档,以及 LTW 主题问题的其他答案,一切都应该没问题,或者我遗漏了什么?

java spring aop xml-configuration load-time-weaving

评论

0赞 kriegaex 2/24/2023
你忘了添加或类似吗?-javaagent:/path/to/aspectjweaver-1.9.19.jar
0赞 Sergejs Jevstigņejevs 2/24/2023
如果我添加它,则不会有任何变化。以及它不是已经通过 IntelliJ -javaagent 使用过吗?(好吧,aspectjweaver 在 -classpath 中指定,但 IntelliJ idea_rt.jar在 -javaagent 中指定)
0赞 kriegaex 2/25/2023
IntelliJ javaagent 与 AspectJ 完全无关,您确实需要 JVM 命令行上的 AspectJ weaver 作为 Java 代理,而不仅仅是在类路径上。

答:

0赞 kriegaex 2/25/2023 #1

您是否不小心将选项添加到程序参数而不是 VM 参数中?对我来说,你的项目运作良好。-javaagent

IntelliJ IDEA: select VM options

IntelliJ IDEA: show added VM options

运行程序将产生:

[AppClassLoader@1d44bcfa] info AspectJ Weaver Version 1.9.19 built on Wednesday Dec 21, 2022 at 06:57:22 PST
[AppClassLoader@1d44bcfa] info register classloader jdk.internal.loader.ClassLoaders$AppClassLoader@1d44bcfa
[AppClassLoader@1d44bcfa] info using configuration .../target/classes/META-INF/aop.xml
[AppClassLoader@1d44bcfa] info register aspect com.sj.aspects.MonitoringAspect
[--add-opens=java.base/java.lang=ALL-UNNAMED, -javaagent:src/main/resources/aspectjweaver-1.9.19.jar, -javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.1.3\lib\idea_rt.jar=56248:C:\Program Files\JetBrains\IntelliJ IDEA 2019.1.3\bin, -Dfile.encoding=UTF-8]
...
[AppClassLoader@1d44bcfa] weaveinfo Join point 'method-execution(void com.sj.utilities.Watch.sleeping(long))' in Type 'com.sj.utilities.Watch' (Watch.java:9) advised by around advice from 'com.sj.aspects.MonitoringAspect' (MonitoringAspect.java)
Before void com.sj.utilities.Watch.sleeping(long) execution!
Slept 3000 ms
Method's execution time:
    3010467900 ns
    3010467 μs
    3010 ms
    3 s
After void com.sj.utilities.Watch.sleeping(long) execution!

评论

0赞 Sergejs Jevstigņejevs 2/25/2023
好吧,不,我将其添加到 JVM 参数中。但归根结底,罪魁祸首是这个 JVM 参数: .它阻止了横切功能的工作。-Dorg.aspectj.weaver.loadtime.configuration=trace
0赞 kriegaex 2/26/2023
天哪,你为什么要使用异国情调的设置,甚至不提它?你能不能从简单而不是复杂开始?我觉得我浪费了很多时间,克隆你的项目,试图重现你的问题,在这里写信并为你制作额外的屏幕截图。😕 请学习如何提问。