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

Spring是否会触发类的静态初始化块执行?

Spring类扫描是否会触发静态初始化块执行

核心结论

绝大多数场景下,Spring扫描类注解的动作不会触发目标类的静态初始化块执行,只有当Spring实际需要实例化类、调用类静态方法/访问类静态字段时,才会触发类的初始化流程,执行静态块。

具体原因

Java的类加载流程分为3个核心阶段:

  • 加载:读取类的字节码文件,在内存中生成对应的Class对象
  • 链接:验证字节码合法性、为静态变量分配内存赋默认值、解析符号引用
  • 初始化:执行静态初始化块、给静态变量赋程序员指定的初始值

Spring扫描类注解的动作,只会用到第一阶段加载得到的Class对象的元数据,不会触发类的初始化阶段:

Spring底层扫描类时,默认通过ASM框架直接读取字节码文件的注解信息,甚至不会走JVM的类加载流程加载该类;即便是需要通过Class.forName获取Class对象的场景,Spring也会调用带3个参数的重载方法Class.forName(className, false, classLoader),其中第二个参数initialize设为false,明确告知JVM不要执行类的初始化动作。

特殊例外情况

只有两种情况Spring扫描过程可能意外触发静态块执行:

  • 你自定义了BeanDefinition扫描逻辑,调用Class.forName时主动将initialize参数设为true
  • 类的字节码本身存在特殊字节码增强逻辑,在类加载的链接阶段就主动触发了初始化操作(这种情况和Spring本身无关,属于类本身的特殊实现)

代码验证示例

你可以用下面的代码自行验证:

// 带静态块的测试类
@Component
public class TestStaticClass {
    static {
        System.out.println("静态初始化块被执行了");
    }
}

// Spring启动类
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        // 只扫描BeanDefinition,不实例化
        GenericApplicationContext context = new GenericApplicationContext();
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
        scanner.scan("com.example.demo");
        System.out.println("Bean扫描完成,还未实例化");
        // 刷新上下文才会实例化Bean,此时才会打印静态块的内容
        context.refresh();
    }
}

运行后可以看到,扫描完成时不会打印静态块的输出,只有刷新上下文实例化Bean时才会触发静态块执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:36:04