为了账号安全,请及时绑定邮箱和手机立即绑定

提升Spring Boot的启动速度

1. 前言

随着我们项目的不断迭代 Bean 的数量会大大增加,如果都在启动时进行初始化会非常耗时。Spring Boot 允许延迟初始化应用程序, 也就是根据需要初始化 Spring Bean,而不是在 Spring Boot 启动时创建所有的 Bean。这样的就可以减少应用程序启动花费的时间。延迟初始化通常又被称为“懒加载”。

2. 延迟初始化

Spring Boot 中的延迟初始化可分为全局延迟初始化局部初始化

注意:以下特性在 Spring Boot 2.2.x 中存在

2.1 全局初始化

全局初始化我们可以通过编程的方式来实现,需要我们来改变 Spring Boot Main方法的写法。

通常我们的 Main 方法是这样的,注意这里还没声明全局懒加载

/**

  • @author felord.cn
  • @since 2020/3/31 22:53
    */
    @SpringBootApplication
    public class DemoSpringbootApplication {
    @Lazy
    public static void main(String[] args) {
    SpringApplication.run(DemoSpringbootApplication.class,args);
    }
    }

全局懒加载写法一:

/**

  • @author felord.cn
  • @since 2020/3/31 22:53
    */
    @SpringBootApplication
    public class DemoSpringbootApplication {
    @Lazy
    public static void main(String[] args) {
    SpringApplication sa = new SpringApplication(DemoSpringbootApplication.class);

    sa.setLazyInitialization(true);
    sa.run(args);
    }
    }

全局懒加载写法二:

/**

  • @author felord.cn
  • @since 2020/3/31 22:53
    */
    @SpringBootApplication
    public class DemoSpringbootApplication {
    @Lazy
    public static void main(String[] args) {
    SpringApplicationBuilder sab = new SpringApplicationBuilder(DemoSpringbootApplication.class);

sab.lazyInitialization(true).run(args);
}
}

上面的写法一和写法二都是我们通过编程方式定制一些 Spring Boot 特性,大多数都是全局特性。包括本文讲述的 “懒加载”。

我们还可以采取更简单的配置文件(application.properties)的方式来配置延迟初始化:

默认是关闭的 false

spring.main.lazy-initialization=true

当我们开启了全局的延迟加载后,在 Web 应用程序中将导致许多与 Web 相关的 Bean 直到收到第一次 HTTP 请求后才被初始化。

控制器

/**

  • @author felord.cn
  • @since 2020/3/31 23:31
    */
    @RestController
    @RequestMapping
    public class FooController {
    private FooService fooService;

public FooController(FooService fooService) {
System.out.println(“fooController init…”)
this.fooService = fooService;
}

@GetMapping("/req")
public Map<String, String> demo() {
System.out.println(“Preparing HTTP request…”);
return fooService.response();
}

}

服务层

/**

  • @author felord.cn
  • @since 2020/3/31 23:36
    */
    @Service
    public class FooService {
    public FooService() {
    System.out.println(“fooService init …”);
    }

    public Map<String, String> response() {
    Map<String, String> map = new HashMap<>();
    map.put(“msg”,“from fooService”);
    return map;
    }
    }

调用 /req 接口后我们发现,不单单 FooControllerFooService 在第一次调用初始化,连 Spring MVC 核心 DispatcherServlet 都是第一次调用时初始化。

2.2 局部初始化

如果我们不想让全局延迟初始化作用于个别的 Bean 怎么办?我们可以在这个 Bean 上声明注解 @Lazy(value = false) 即可。你可以改写 2.1 的代码自己试一试。这个 @Lazy 作用于局部,并通过布尔值 value 来控制是否延迟初始化。情况是这样的:

  • 当我们声明全局延迟加载时,@Lazy(value = false)标记的 Bean 会被立即加载。

  • 当我们声明全局延迟加载时,@Lazy 标记的 Bean 会被延迟加载。

请注意:@Lazy 会影响到 @Configuration 下声明的 Bean

3. 注意事项

延迟初始化的缺点是,如果错误配置的 Bean 是延迟初始化的,则在启动期间将不再发生故障,并且只有在初始化 Bean 时错误才会暴露出来,所以一定要经过严格的测试。

同时还必须注意确保 JVM 具有足够的内存来容纳所有应用程序的 Bean,而不仅仅是启动期间初始化的 Bean。因此建议在启用延迟初始化之前先对 JVM 的堆大小进行必要的检测和微调以保证不会溢出。

那些初始化耗时,具有复杂逻辑,而且不是启动的必要选择的 Bean 应当被延迟初始化。

4. 总结

今天对 Spring Boot 如何进行延迟初始化进行了讲解,同时也说明了一些注意事项。间接地也对 Main 方法的几种姿势也进行了展示,希望对你的实际开发有所帮助。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消