Spring 不使用 SoftReference 缓存 BeanDefinition,因其需全程强引用保障元数据稳定可用;仅在 ResolvableType 类型推导等非核心场景谨慎使用软引用缓存。

Spring 框架本身在标准的 ApplicationContext 加载流程中,并不使用 SoftReference 来缓存类定义(BeanDefinition)元数据。
Spring 的 BeanDefinition 缓存机制是强引用
Spring 在解析配置(XML、JavaConfig、注解扫描等)后,会将所有 BeanDefinition 实例统一注册到 BeanDefinitionRegistry(如 DefaultListableBeanFactory)中。这些定义对象以 ConcurrentHashMap 或普通 Map 存储,持有强引用:
-
beanDefinitionMap:键为 bean 名称,值为BeanDefinition对象(如RootBeanDefinition),生命周期与容器一致; - 即使 JVM 内存紧张,只要上下文未关闭,这些定义不会被 GC 回收;
- 这是设计使然——
BeanDefinition是容器运行时的核心元数据,必须随时可用,不可“临时丢失”。
SoftReference 不适合 BeanDefinition 缓存场景
SoftReference 的语义是“内存不足时可被回收”,但 Spring 的元数据有明确的生命周期契约:
- 应用启动后,
BeanDefinition需稳定存在,用于后续实例化、依赖注入、AOP 增强等; - 若某次 GC 后部分定义被清除,再次获取时无法重建(原始配置源可能已不可达,如流已关闭、Class 字节码未缓存);
- Spring 的设计哲学是确定性与可控性,而非依赖 GC 行为做缓存淘汰。
真正用到 SoftReference 的 Spring 组件:类型匹配缓存
Spring 在极少数内部优化路径中谨慎使用了软引用,最典型的是 ResolvableType 的解析结果缓存:
-
ResolvableType.forClass(...)等方法会缓存泛型类型推导结果; - 该缓存由
ResolvableType#cache(ConcurrentReferenceHashMap)管理,默认使用SOFT引用策略; - 原因:类型推导开销较高(尤其嵌套泛型),但结果非核心状态,且可安全重计算;内存压力下丢弃也无副作用。
如需自定义软引用缓存,应独立封装而非侵入 Spring 核心
若你在扩展 Spring(如自研注解处理器、元数据预分析器)时希望缓存某些中间结果(如扫描出的候选类、条件评估快照),可自行结合 SoftReference:
- 用
ConcurrentReferenceHashMap(Spring 自带,支持软/弱引用)替代原生 Map; - 确保缓存值可重建(例如保存类名而非 Class 对象,避免 ClassLoader 泄漏);
- 避免缓存
BeanDefinition本身——它持有很多强引用(如ConstructorArgumentValues、PropertyValues),软引用意义不大。
不复杂但容易忽略:Spring 的稳健性正来自对引用策略的克制——关键元数据用强引用保正确,辅助计算用软引用提效率,边界清晰,各司其职。

















