You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Instrument API的Agent无法检测SpringBoot未扫描的Chap03类

问题分析与解决

核心原因

你遇到的问题本质是类加载时机导致的:

  • 当Chap03没有@Configuration这类注解时,它既没被Spring上下文扫描到,也没被其他业务代码引用,JVM会采用延迟加载策略,根本不会加载这个类,所以你的Transformer自然捕获不到。
  • premain里的Class.forName失败,是因为Agent的类加载器(系统类加载器)和SpringBoot应用的类加载器(LaunchedURLClassLoader)不是同一个,系统类加载器找不到应用包下的类。

具体解决方案

1. 强制触发类加载(最简单直接)

在SpringBoot主类里显式引用Chap03,哪怕只是声明一个无用的变量,让JVM在启动时加载该类:

@SpringBootApplication
public class YourSpringBootMain {
    // 声明变量触发类加载
    private static Chap03 dummy = new Chap03();

    public static void main(String[] args) {
        SpringApplication.run(YourSpringBootMain.class, args);
    }
}

2. 调整Agent的类加载逻辑

在premain中,先添加Transformer,再尝试用应用类加载器加载目标类:

public static void premain(String agentArgs, Instrumentation instrumentation)  {
    Banner.send(agentArgs);
    ConfigRead configRead = new ConfigRead();

    // 先添加Transformer,再尝试加载类
    instrumentation.addTransformer(new Chap03Transformer());

    // 获取应用类加载器(SpringBoot的LaunchedURLClassLoader)
    ClassLoader appClassLoader = Thread.currentThread().getContextClassLoader();
    try {
        // 用应用类加载器加载目标类
        Class.forName("com.dummy.jdbcserver.example_asm.Chap03", true, appClassLoader);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

注意:必须先添加Transformer再加载类,否则加载类的时候Transformer还没生效。

3. 利用Spring的扫描机制

除了@Configuration,你也可以给Chap03加更轻量的注解比如@Component,同时确保SpringBoot的@ComponentScan覆盖该类所在的包:

@Component // 替换@Configuration,更轻量
public class Chap03 {
    // ... 原有代码
}

这样Spring上下文启动时会扫描并加载该类,Transformer就能捕获到。

4. 遍历已加载类并触发重转换

如果类已经被加载(比如启动后动态加载),可以用Instrumentation的retransformClasses方法触发转换:

// 在premain或者后续JMX线程中执行
for (Class<?> clazz : instrumentation.getAllLoadedClasses()) {
    if (clazz.getName().contains("Chap03")) {
        try {
            instrumentation.retransformClasses(clazz);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

这个方法适合类已经被加载但没被转换的场景。

额外注意点

  • Transformer中的className是用斜杠分隔的(比如com/dummy/jdbcserver/example_asm/Chap03),你的contains("Chap03")逻辑没问题,但可以更精准:className.endsWith("/Chap03")
  • 确保Agent的jar包被正确配置到SpringBoot的启动参数中(比如-javaagent:your-agent.jar)

内容的提问来源于stack exchange,提问作者Leon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 02:52:46