导读:本期聚焦于小伙伴创作的《Spring Boot 整合时如何使用 @EnableLazy 控制 Bean 延迟初始化?》,敬请观看详情。应用启动变慢往往和 Bean 过早实例化有关。Spring Boot 默认在容器刷新阶段就创建绝大多数单例 Bean,若其中含有重型资源连接或复杂计算,会明显拖长启动时间。@EnableLazy 注解能从配置入口统一开启延迟初始化,让 Bean 在首次被依赖注入或显式获取时才实例化。本文说明该注解在 Spring Boot 整合中的具体位置、与全局配置的差异,以及哪些场景不适合全量懒加载。理解这些要点可避免把普通业务 Bean 误设为懒加载后引发的循环依赖隐藏问题,也能借助延迟化缩短微服务冷启动耗时。

在 Spring Boot 项目里,容器启动时会默认把上下文中几乎所有的单例 Bean 提前实例化并完成依赖装配。当工程里包含大量涉及数据库连接池、Redis 客户端或者复杂算法初始化的组件时,这种饿汉式加载会让启动过程变得很慢。@EnableLazy 是 Spring 框架提供的用于开启延迟初始化的注解,把它加在配置类上,可以让对应范围内的 Bean 推迟到真正被使用的时候才创建。在整合 Spring Boot 的过程中,合理地使用这个注解,是优化启动性能的一种直接手段。

Spring Boot 整合时如何使用 @EnableLazy 控制 Bean 延迟初始化?

@EnableLazy 的基本用法与整合位置

@EnableLazy 本身来自 Spring 的 org.springframework.context.annotation 包,它作为一个元注解组合了 @Configuration 的能力,并导入了处理懒加载的后置处理器。在 Spring Boot 应用中,我们通常不会单独写一个被 @EnableLazy 标注的配置类,而是把它放在主启动类或者某一层业务配置上。需要注意,Spring Boot 2.2 之后也提供了 spring.main.lazy-initialization=true 的全局属性,但 @EnableLazy 的优势在于可以精确到某一个 @Configuration 类所对应的 Bean 定义区域。

下面是一段典型的整合代码,我们在数据访问层的配置类上使用 @EnableLazy,使得该配置中定义的 Mapper 或相关仓储 Bean 不被提前初始化:

package com.example.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableLazy;

@Configuration
@EnableLazy
public class DataAccessConfig {

    // 此处定义的 Bean 在容器启动阶段不会实例化
    // 只有当其他组件首次注入或使用它们时才会创建
}

从容器生命周期角度看,@EnableLazy 实际是给对应的 BeanDefinition 设置了 isLazyInit 的标记。在 AbstractApplicationContextfinishBeanFactoryInitialization 方法中,Spring 会跳过那些被标记为懒加载的单例 Bean。这意味着即便你的工程里有上百个 Bean,只要它们处在这个配置类的扫描或注册范围内,启动时就只会注册定义而不会占用实例化时间。

与全局懒加载配置的差异及选型

很多开发者在搜 Spring Boot 优化启动时间时,会直接打开 application.properties 写下 spring.main.lazy-initialization=true。这种做法和 @EnableLazy 最大的不同在于作用域。全局配置会影响整个应用上下文中的所有单例 Bean,而 @EnableLazy 仅影响它所在配置类及其导入的 Bean。若你的系统里有部分 Bean 必须在启动时完成预热,比如监听端口的 Web 服务器、健康检查指示器,那么全局懒加载可能会让这些关键组件延迟就绪,从而导致健康检查失败或第一批请求极慢。

通过对比可以更清楚地看到两者的适用边界:

方式作用范围配置复杂度风险点
全局 lazy-initialization整个 ApplicationContext一行属性核心基础设施延迟导致启动后抖动
@EnableLazy 注解特定配置类区域需拆分配置范围划分不清时部分 Bean 仍早加载

在实际整合中,推荐将重型、非核心的组件配置独立成带有 @EnableLazy 的配置类,而把 Web、监控等基础配置留在默认饿汉加载中。这样既享受了延迟初始化带来的启动加速,又不会破坏 Spring Boot 内嵌服务器的正常就绪流程。需要特别留意,被 @ComponentScan 扫到的普通 @Service 若不在该配置类名下,是不会继承这个懒加载属性的。

延迟初始化下的循环依赖与避坑实践

使用 @EnableLazy 之后,一个容易忽视的问题是循环依赖的表象变化。在默认饿汉加载时,Spring 会通过提前暴露半成品 Bean 来解决构造器之外的循环依赖;但当你把其中一侧设为懒加载,这个 Bean 在启动阶段根本不会被创建,于是循环依赖的报错可能会消失,转而变成第一次调用时才抛出 BeanCurrentlyInCreationException。这种延迟暴露的故障在测试阶段很难发现,往往要到生产环境真实流量进来才显现。

为了避免这类隐患,应当在开启 @EnableLazy 的同时,梳理被延迟 Bean 之间的引用关系。如果 A 和 B 互相依赖,且 A 被懒加载,那么首次获取 A 时会创建 A,接着填充属性时去拿 B,而 B 若不是懒加载且已经早先创建好,则没有问题;但如果 B 也依赖 A 的某一方法并返回新实例,就可能触发嵌套创建。下面示例展示如何用 @Lazy 注解配合 @EnableLazy 做细粒度控制:

@Service
public class OrderService {

    private final PaymentService paymentService;

    // 在注入点也声明懒加载,确保 PaymentService 不会在 OrderService 创建时立刻被拉起
    public OrderService(@Lazy PaymentService paymentService) {
        this.paymentService = paymentService;
    }

    public String createOrder() {
        return paymentService.pay() + ":done";
    }
}

另一个实践要点是监控延迟 Bean 的首次实例化耗时。由于它们被推迟到业务请求阶段,若某个 Bean 内部要建连远程服务,第一次接口调用就会承担这部分成本。建议配合 Spring Boot 的 Metrics 或简单的日志,在 Bean 的 @PostConstruct 中打印耗时,确认延迟初始化没有把启动慢转化成了接口慢。只有把范围控制合理、依赖梳理清楚,@EnableLazy 在 Spring Boot 整合中才真正起到既快又稳的作用。

Spring_BootEnableLazyBean_lazy_initialization修改时间:2026-08-13 22:54:31

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。