JVM类加载与spring框架中bean的加载的联系与区别
【摘要】 jvm类加载与spring bean的加载的联系与区别整理
简要说明
- JVM 类加载机制:面向 类(Class) 的生命周期管理
- Spring Bean 生命周期:面向 对象(Instance) 的生命周期管理
JVM 类加载过程(类级别)
1. 加载(Loading)
- 类加载器读取
.class
文件,生成Class
对象。
2. 链接(Linking)
- 验证:字节码合法性检查
- 准备:为
static
字段分配内存并赋默认值(0
,null
),如果是final修饰的,则直接赋值常量值 - 解析:符号引用 → 直接引用
3. 初始化(Initialization)
- 执行
<clinit>
方法(静态代码块、static
字段赋值) - 类才算真正可用
Spring Bean 生命周期(对象级别)
1. 实例化(Instantiation)
- 通过反射调用构造器创建对象(此时 JVM 已经完成类加载)
2. 属性注入(Populate Properties)
- 依赖注入(DI),为字段/Setter 注入依赖
3. 初始化(Initialization)
- 调用
@PostConstruct、InitializingBean.afterPropertiesSet()、init-method
- 执行
BeanPostProcessor
的前置/后置处理
4. 使用(In Use)
- Bean 被容器和应用程序使用
5. 销毁(Destruction)
- 容器关闭时,调用
@PreDestroy、DisposableBean.destroy()、destroy-method
两者的联系
层次 | JVM 类加载 | Spring Bean 生命周期 | 联系点 |
---|---|---|---|
类级别 | 加载 → 链接 → 初始化 | —— | Spring Bean 的类必须先被 JVM 加载,才能被实例化 |
对象级别 | new 创建对象 |
实例化 → 属性注入 → 初始化 → 销毁 | Spring Bean 的实例化依赖 JVM 的对象创建机制 |
静态资源 | static 字段在类初始化时赋值 |
Bean 的依赖注入和初始化 | JVM 负责类的静态部分,Spring 负责对象的依赖和生命周期 |
扩展机制 | 反射、动态代理、字节码增强 | AOP、依赖注入、BeanPostProcessor | Spring 大量利用 JVM 提供的反射和代理能力 |
Spring Bean 生命周期完全建立在 JVM 类加载机制之上。换句话说,没有 JVM 的类加载,就没有 Spring Bean 的实例化。
拓展
JVM 层面
- 在 JVM 中,类被加载后会在 方法区(JDK8 之后是元空间 Metaspace) 中存放该类的结构信息(字段、方法、常量池、类元数据等)。
- 这个
Class
对象(在堆中)是对方法区中类元数据的一个运行时映射。 - 当我们执行
new
或者通过反射Class.newInstance()
时,JVM 就是根据这个Class
对象来分配堆内存并调用构造方法,生成实例对象。 - 实例化对象的“蓝图”就是方法区里的类信息,具体的入口是堆中的
Class
对象。
Spring 层面
- Spring Bean 的实例化,本质上还是依赖 JVM 的对象创建机制。
- Spring 先根据
BeanDefinition
找到目标类的Class
对象(这个类早已由 JVM 加载到方法区/元空间)。 - 然后通过 反射 或 工厂方法 来调用构造器,最终在堆中生成一个对象实例。
- Spring 并不会自己“造对象”,它只是利用 JVM 提供的
Class
元数据和反射机制来完成实例化。
总结
Spring 通过 Class
对象(堆中)拿到类的元数据(方法区/元空间中),再用反射去实例化对象(堆中)。
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)