1. 概述

从 Spring Boot 2.2 开始,官方引入了全局懒加载配置,使得开发者可以更灵活地控制 Spring 容器中 Bean 的初始化时机。本文将带你深入了解如何在 Spring Boot 应用中启用和使用懒加载机制。


2. 什么是懒加载(Lazy Initialization)

默认情况下,Spring 容器会在启动时加载所有 Bean 及其依赖。✅

懒加载则不同:只有在真正需要某个 Bean 时,才会进行实例化和依赖注入。

这种机制可以有效减少应用启动时的资源消耗,但也会带来一些潜在问题,我们后面会详细分析。


3. Maven 依赖

要使用 Spring Boot 的懒加载功能,只需要引入标准的 Spring Boot Starter:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>3.1.5</version>
    </dependency>
</dependencies>

4. 启用懒加载机制

从 Spring Boot 2.2 开始,可以通过配置 spring.main.lazy-initialization 属性,全局启用懒加载机制

✅ 配置方式如下:

application.yml:

spring:
  main:
    lazy-initialization: true

application.properties:

spring.main.lazy-initialization=true

⚠️ 注意事项:

  • 该配置作用于整个应用上下文中的所有 Bean。
  • 如果你只想对某个特定 Bean 启用懒加载,推荐使用 @Lazy 注解。
  • 也可以将 @Lazy(false) 用于某些 Bean,从而全局启用懒加载,仅对特定 Bean 禁用懒加载

4.1 使用 SpringApplicationBuilder 启用懒加载

SpringApplicationBuilder(Application.class)
  .lazyInitialization(true)
  .build(args)
  .run();

4.2 使用 SpringApplication 启用懒加载

SpringApplication app = new SpringApplication(Application.class);
app.setLazyInitialization(true);
app.run(args);

⚠️ 优先级说明:配置文件中的属性优先级高于代码中设置的 flag。


5. 实战演示

我们创建一个简单的服务类来观察懒加载的效果:

public class Writer {

    private final String writerId;

    public Writer(String writerId) {
        this.writerId = writerId;
        System.out.println(writerId + " initialized!!!");
    }

    public void write(String message) {
        System.out.println(writerId + ": " + message);
    }
}

再创建主类并注册两个 Bean:

@SpringBootApplication
public class Application {

    @Bean("writer1")
    public Writer getWriter1() {
        return new Writer("Writer 1");
    }

    @Bean("writer2")
    public Writer getWriter2() {
        return new Writer("Writer 2");
    }

    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Application.class, args);
        System.out.println("Application context initialized!!!");

        Writer writer1 = ctx.getBean("writer1", Writer.class);
        writer1.write("First message");

        Writer writer2 = ctx.getBean("writer2", Writer.class);
        writer2.write("Second message");
    }
}

测试结果对比:

未启用懒加载 (spring.main.lazy-initialization=false):

Writer 1 initialized!!!
Writer 2 initialized!!!
Application context initialized!!!
Writer 1: First message
Writer 2: Second message

启用懒加载 (spring.main.lazy-initialization=true):

Application context initialized!!!
Writer 1 initialized!!!
Writer 1: First message
Writer 2 initialized!!!
Writer 2: Second message

✅ 可见:Bean 在第一次被使用时才初始化,而不是在应用启动时。


6. 懒加载的优缺点分析

✅ 优点:

  1. 提升启动速度:减少启动时创建的 Bean 数量。
  2. 节省资源:避免加载未使用的 Bean,降低内存占用。

❌ 缺点:

  1. 掩盖启动期问题:一些配置错误或依赖缺失的问题可能在运行时才暴露,增加排查难度。
  2. 可能导致运行时异常:例如内存溢出、类找不到、配置错误等。
  3. 影响首请求性能:在 Web 应用中,首次访问接口时才创建 Bean,可能增加响应延迟。
  4. 影响负载均衡与自动扩缩容:首请求的延迟可能导致健康检查失败,影响系统稳定性。

7. 总结

通过 Spring Boot 2.2 引入的 spring.main.lazy-initialization 配置项,我们可以非常方便地在整个应用中启用懒加载机制。✅

适用场景建议:

  • 开发环境或测试环境:推荐开启,提升启动效率。
  • 生产环境:建议谨慎使用,或仅对非关键路径 Bean 启用,避免影响可用性。

如需查看完整示例代码,可前往 GitHub:示例代码地址


原始标题:Lazy Initialization in Spring Boot 2.2

« 上一篇: Java Weekly, 第286期
» 下一篇: JAR 清单文件详解