EnableLoadTimeWeaving注解导致应用上下文加载失败

EnableLoadTimeWeaving annotation causes application context to fail to load

我正在尝试在 Spring 引导应用程序中启用 AspectJ 加载时编织(不是 Spring AOP)。我的目标是在加载时将建议编织到带注释的字段和 java.lang.reflect.Field.set(Object, Object) 中。

根据 Spring docs,我试过:

@Configuration
@EnableLoadTimeWeaving
public class Config {}

运行 使用此配置的 Spring 引导应用程序导致应用程序上下文加载失败并显示此消息:

Caused by: java.lang.IllegalStateException:
  ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader]
    does NOT provide an 'addTransformer(ClassFileTransformer)' method.
    Specify a custom LoadTimeWeaver or start your Java virtual machine
    with Spring's agent: -javaagent:spring-instrument-{version}.jar

该消息中的后一个建议不是一个好的选择,因为我试图避免必须修改启动脚本。我需要编织的方面实际上驻留在一个库中,因此所有实施 Spring 引导项目都必须进行使 LTW 工作所需的任何更改。

我也试过这个配置:

@Configuration
@EnableLoadTimeWeaving
public class Config implements LoadTimeWeavingConfigurer {

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

运行 使用此配置的 Spring 引导应用程序导致应用程序上下文加载失败并显示此消息:

Caused by: java.lang.IllegalStateException:
  ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader]
    does NOT provide an 'addTransformer(ClassFileTransformer)' method.

看来我需要让 JVM 使用具有 addTransformer(ClassFileTransformer) 方法的 class 加载程序。我不知道该怎么做,特别是对于这种情况。有什么建议吗?

我不是活跃的 Spring 用户,但我知道 Spring 支持注释或 XML-configured 代理 hot-attachment 并且有一些 container-specific 类 为据其 documentation。不过,它似乎并非在所有情况下都能可靠地工作,尤其是当 运行 从 IDE 左右启动 Spring 应用程序时。

总之,AspectJ weaver 1.8.7 and more recent can be hot-attached. I explained how to do that in a Spring setup . If you want a simpler solution with less boilerplate but one more dependency to a tiny helper library called byte-buddy-agent, you can use this solution为捷径。我没有尝试过,但我知道帮助程序库,并且在 hot-attaching 字节码检测代理时我自己在其他上下文中使用它,避免大惊小怪地迎合不同的 JVM 版本和配置情况。但是为了让它在 JVM 9+ 上工作,您可能需要为 JVM 手动激活 auto-attachment,这将是对您的 start-up 脚本的另一个修改,您将回到方块 1。