点击上方蓝色“程序猿DD”,选择“设为星标”

回复“资源”获取独家整理的学习资料!

来源 | 公众号「码农小胖哥」

1. 前言

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

2. 延迟初始化

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

2.1 全局初始化

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

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

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

全局懒加载写法一:

/*** @author felord.cn* @since 2020/3/31 22:53*/
@SpringBootApplication
publicclass DemoSpringbootApplication {@Lazypublic 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
publicclass DemoSpringbootApplication {@Lazypublic 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
publicclass FooController {private FooService fooService;public FooController(FooService fooService) {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
publicclass 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 接口后我们发现,不单单 FooController 和 FooService 在第一次调用初始化,连 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 应当被延迟初始化。

  • 这四个问题场景你会排查原因吗?

  • Code Review 是一场苦涩但有意思的修行

  • 答应我!别再写上千行的类了,好吗?

  • 震精!Spring Boot内存泄露,排查竟这么难!

  • Elasticsearch 在互联网公司大量真实的应用案例

推荐关注本文作者

勤奋高产的码农小胖哥

合理利用延迟初始化优化 Spring Boot相关推荐

  1. 这样优化Spring Boot,启动速度快到飞起!

    微服务用到一时爽,没用好就呵呵啦,特别是对于服务拆分没有把控好业务边界.拆分粒度过大等问题,某些 Spring Boot 启动速度太慢了,可能你也会有这种体验,这里将探索一下关于 Spring Boo ...

  2. 【springboot系列】这样优化Spring Boot,启动速度快到飞起!

    微服务用到一时爽,没用好就呵呵啦,特别是对于服务拆分没有把控好业务边界.拆分粒度过大等问题,某些 Spring Boot 启动速度太慢了,可能你也会有这种体验,这里将探索一下关于 Spring Boo ...

  3. RabbitMQ(九):RabbitMQ 延迟队列,消息延迟推送(Spring boot 版)

    应用场景 目前常见的应用软件都有消息的延迟推送的影子,应用也极为广泛,例如: 淘宝七天自动确认收货.在我们签收商品后,物流系统会在七天后延时发送一个消息给支付系统,通知支付系统将款打给商家,这个过程持 ...

  4. springboot项目实战_2019学习进阶之路:高并发+性能优化+Spring boot等大型项目实战...

    Java架构师主要需要做哪些工作呢? 负责设计和搭建软件系统架构(平台.数据库.接口和应用架构等),解决开发中各种系统架构问题. 优化现有系统的性能,解决软件系统平台关键技术问题攻关.核心功能模块设计 ...

  5. spring boot rabbitmq_Spring Boot+RabbitMQ 实现延迟消息实现完整版,实用!

    本文同步Java知音社区,专注于Java 作者:Sam哥哥http://blog.csdn.net/linsongbin1/article/details/80178122 概述 曾经去网易面试的时候 ...

  6. Spring Boot 性能优化

    Spring 框架给企业软件开发者提供了常见问题的通用解决方案,包括那些在未来开发中没有意识到的问题.但是,它构建的 J2EE 项目变得越来越臃肿,逐渐被 Spring Boot 所替代.Spring ...

  7. 掌握 Spring Boot 运行内存及内存参数设置:助力高效应用部署与优化

    pring Boot 是当今非常流行的 Java 应用框架之一,在企业级应用开发中被广泛使用.应用部署和优化是企业级应用开发的一个非常重要的方面.在这篇博客中,我们将学习如何掌握 Spring Boo ...

  8. spring boot(一):入门篇

    构建微服务:Spring boot 入门篇 什么是spring boot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框 ...

  9. Spring Boot&Angular 5&Spring Data&Rest示例(CRUD)

    本教程提供了Spring Boot,Angular 5和spring数据的完整实现,以示例为例构建端到端的单页Java Web应用程序.我们将使用Spring Boot 1.5公开REST API和a ...

最新文章

  1. 利用ajax技术 实现用户注册。
  2. python操作mongodb之六自定义类型存储
  3. java大组件_Java的三大组件
  4. 使用python将excel数据导入数据库
  5. php从内存中获取源码_PHP源码分析之变量的存储过程分解
  6. python里自带的绘画库是_Python绘图Turtle库详解
  7. sql大小写 效率_【SQL】单行函数
  8. pytorch gather_【CV】10分钟理解Focal loss数学原理与Pytorch代码
  9. 苹果损失超 1000 万美元,前员工被控收回扣、盗窃、欺诈
  10. springBean的作用域
  11. java中do_while求阶乘倒数和,下面的程序是用do_while语句计算10的阶乘。请在程序的......
  12. C#中如何跨窗体传值
  13. 草根程序员转型做项目管理走过的点点滴滴_康奈尔笔记法介绍
  14. Word目录制作修改
  15. 教会如何使用WordPress提供在线讲道
  16. 360插件化方案RePlugin学习笔记-插件与宿主间的通信方式
  17. 水墨特效怎么做?两种方法快速搞定!大神都在用的超美视频画面效果
  18. 3500字归纳总结:一名合格的软件测试工程师需要掌握的技能大全
  19. Activiti设置流程发起人用户信息
  20. 近距离无线通信(NFC)技术介绍

热门文章

  1. golang map range遍历是随机顺序
  2. 内容管理系统 Nuxeo认证绕过和RCE漏洞(CVE-2018-16341) 分析
  3. java 反序列化漏洞 利用思路简介
  4. linux shell putty 无法使用 home end 键
  5. C/C++程序编译过程详解
  6. Nosql简介 Redis,Memchche,MongoDb的区别
  7. WMI问题全解(Windows管理规范)
  8. Linux C编程--进程介绍4--errno
  9. Java学习之switch语句
  10. 深入理解Spark Streaming执行模型