Spring延迟加载本质是将单例Bean实例化推迟至首次使用时,启动时跳过@Lazy Bean的创建,首次getBean或@Autowired调用时才执行完整生命周期并缓存;注入点加@Lazy会生成代理实现按需初始化;prototype Bean不支持@Lazy。

Spring 核心容器实现延迟加载(Lazy Init),本质是把单例 Bean 的实例化动作从容器启动阶段推迟到第一次被使用时,不改变 Bean 的作用域和复用行为,只调整创建时机。
容器启动时跳过实例化
默认情况下,ApplicationContext 启动时会遍历所有单例 BeanDefinition,逐一调用 createBean() 完成实例化、初始化和注册到单例池。而标记 @Lazy 的 Bean,其 BeanDefinition 的 lazyInit = true。容器在预实例化阶段(finishBeanFactoryInitialization)会跳过这些 Bean,仅保留在 beanDefinitionMap 中,不执行任何构造或依赖注入。
首次请求时触发创建与缓存
当代码首次调用 getBean("xxx") 或通过 @Autowired 注入并实际调用方法时,容器检测到该 Bean 是 lazy-init 的单例,就会:
- 通过 ObjectFactory 包装创建逻辑,确保只执行一次;
- 调用标准流程完成实例化、属性填充、初始化(包括 @PostConstruct、InitializingBean);
- 将实例放入 singletonObjects 缓存,后续所有请求都直接返回该对象。
注入点延迟:代理机制介入
若在字段或构造器参数上加 @Autowired @Lazy,即使目标 Bean 本身未标注 @Lazy,Spring 也会为它生成一个懒加载代理(JDK 动态代理或 CGLIB)。这个代理不持有真实实例,直到第一次调用任意方法时,才触发目标 Bean 的创建与初始化,并缓存结果供后续复用。
立即学习“Java免费学习笔记(深入)”;
不适用于 prototype Bean
@Lazy 对 prototype Bean 没有实际效果。因为 prototype 本就是每次 getBean() 都新建,不存在“启动预创建”环节;延迟与否在语义上无差别,Spring 也不会为其生成额外代理或延迟包装。


















