前言

在 2021 年这个小学作文中的未来年份,没有想象中的汽车满天飞,也没有实现机器人满地跑。但牛逼的是我们都有一个共识: 知乎达到了人均 “谢邀~ 人在美国刚下飞机”的生活水平,虎扑的人均收入也在 30W+ ,还有就是程序员都人均精通 SpringBoot ,哪怕和算法聊技术一言不合就满嘴 SpringCould 分布式、微服务,然而实际操作可能是 分步试伪服务 ... 你一个小小系统开这么多应用启动不难受?(不难受因为可以装 13) SpringBoot 这启动速度也确实令人捉急,每个应用 5 分钟改个小功能,编码五分钟部署俩小时。 so 如何更加优雅快速的 启动 SpringBoot 应用 (满足装 13 的欲望) 呢?

其实我们都比较清楚大部分的启动时间是由于 Spring 需要加载各种 Bean 导致启动速度下降的,那么对于那些不是特别重要的 Bean 我们是不是可以让他再起一个线程做 Bean 初始化,不阻塞主线程启动,这样启动速度不就起来了么,说干就干!

那你肯定会问,我们咋判断一个 Bean 加载时间长短,找出那些 拉跨的Bean  呢?内心一阵嘲讽,嘴角泛出一阵冷笑后 不慌不忙的道来:“这对于精通 Spring 框架的我来说不是小菜一碟么 ”。我掐指一算,就知道是哪几个 Bean 拉跨。

统计 Bean 初始化时间

简单做法就是通过 BeanPostProcessor ,祭出这个神器就能干倒一半的 LSP,很多使用 Spring 的 LSP 其实都不太知道这个玩意,那他到底是个什么玩意呢?简单来讲就是 Spring 初始化 Bean 的钩子函数。 Bean 是否加载,加载的是哪个 Bean 以及修改 Bean 的相关属性都可以通过这个钩子函数搞定。这就是一个活生生的 Spring 后门,学会了他 Spring 框架任你摆布。

后面我会专门开一篇文章去讲解 BeanPostProcessor 如何帮你加载 Bean,以及如何利用这个后门搞事情。

所以我们现在讲讲如何用 BeanPostProcessor 统计 Bean 的初始化时间。不多 BB 直接上代码:

我们编写了 BeanInitCostTimeBeanPostProcessor 继承了 BeanPostProcessor 实现了 postProcessBeforeInitialization 和 postProcessAfterInitialization 分别代表了 Bean 初始化之前和之后,简单记录了 Bean 初始化开始时间,然后用结束时间减去开始时间就得到了具体的初始化时间。

我专门在 Spring 容器中放了一个加载时间很长的测试 Bean ,代码如下

效果如下:

异步 Bean 实操

异步 Bean 异步 Bean ,首先这个 Bean 需要是个异步的,那如何将一个 Bean 包装成异步的呢?首先异步 Bean 肯定需要继承原来的 Bean 需要保证是同一种类型的,然后重写他的 init 方法。代码操作如下:

但是这么写并不是很优雅,假如我们还需要在初始化 Bean 的时候做一些其他操作,直接继承是不方便的。所以必须祭出 Spring 中的另外一个组件了,工厂 Bean,学名 FactoryBean 这个要和另外一个叫做 BeanFactory 的大佬区分开。 工厂 Bean 顾名思义就是这个玩意也是一个 Bean 只是他的主要职责是作为工厂,通常用于生成特定类型的 Bean ,那么我们就有一个骚操作了,让这个工厂生产的 Bean 就是它自己,而且中间还能定义很多额外的逻辑,不多 BB 上代码

然后通过异步 Bean 去加载我们看看前后的差别

优化之前:

优化之后:

可以看到优化后 1.4s 应用就启动完成了,而且耗时的 Bean 可以让他慢慢加载,在应用启动完成后这个 Bean 才完全被加载。

唠叨

最近有点忙成狗,从四月就断更到现在了,今天抽个周末的时候终于写完了。

不过最近看了好几本书,也准备抽点时间写写读后感了,非常推荐大家看看 《零秒思考》 ,同时写点个人的小思考: 一旦适应了用语言表达脑海中的意向和感觉,渐渐地就不会为如何表达自己的心情和想法而苦恼,流畅清晰的表达能够更快的与对方沟通让对方心领神会。表达不善往往便会产生一种想也是白想的放弃心理,由此甚至连思考本身也放弃了,不思考人就不会成长,不经历思考解决手头的事情人就会失去干劲变得无聊。

SpringBoot 启动慢?那是因为你不知道它的更多相关文章

  1. springboot启动太慢优化

    需求缘起:有人在[springboot]微信公众号问:springboot启动慢的问题何时有个分享就好了,谢谢.粉丝的问题还是要认真的回答的. 我们先看看本节的大纲: (1)组件自动扫描带来的问题(@ ...

  2. SpringBoot启动流程分析(六):IoC容器依赖注入

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

  3. SpringBoot启动流程分析(三):SpringApplication的run方法之prepareContext()方法

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

  4. springboot启动后自动退出

    有时新建的springboot启动后自动退出运行,如图所示: 此种情况大都数是因为pom文件加入了tomcat的依赖,与springboot内嵌的tomcat冲突导致,所以只需将pom文件中的tomc ...

  5. Springboot启动一直卡在{dataSource-1} inited

    Springboot启动一直卡在{dataSource-1} inited 错误原因: 暂时未知,猜测是因为设置端点的问题 解决办法: 去除所有断点: 然后再次启动就好了. 如果还有错: 那么重新导入 ...

  6. 【转载】springboot启动报错(Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWe)

    SpringBoot启动时的异常信息如下: 1 "C:\Program Files\Java\jdk1.8.0_161\bin\java" ......... com.fangxi ...

  7. springboot启动过程

    使用了很长时间的springboot了,一直都知道它简单易用,简化了框架的搭建过程,但是还是不知道它是如何启动的,今天就跟着springboot的源码,去探探这其中的奥妙 以下是spring应用的启动 ...

  8. SpringBoot启动使用elasticsearch启动异常:Received message from unsupported version:[2.0.0] minimal compatible

    SpringBoot启动使用elasticsearch启动异常:Received message from unsupported version:[2.0.0] minimal compatible ...

  9. 微服务中springboot启动问题

    log4j:WARN No appenders could be found for logger (org.springframework.web.context.support.StandardS ...

  10. (四)SpringBoot启动过程的分析-预处理ApplicationContext

    -- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇(三)SpringBoot启动过程的分析-创建应用程序上下文,本文将分析上下文创建完毕之后的下一步操作:预处理上下文容器. 预处理上下文 ...

随机推荐

  1. React 中的 onInput/onChange

    参考链接:https://stackoverflow.com/questions/38256332/in-react-whats-the-difference-between-onchange-and ...

  2. Pycharm模块导入失败,带有红色波浪线。

    在Pycharm中打开一个python开源工程,结果在导入库的部分一堆红色波浪线显示错误,并且按住Ctrl + 鼠标左击无法跳转到指定类或方法,如下图所示. 解决方法: (1)首先忽略掉这些报错,先运 ...

  3. E: Some index files failed to download. They have been**

    转: E: Some index files failed to download. They have been** 问题描述: 当使用Dockerfile从包含cuda的镜像建立新的image的时 ...

  4. 使用ASP.NET Blazor Server 写混合桌面程序的疯狂想法

    开发本地桌面程序,使用进程内浏览器+进程内BLAZOR服务器,然后任性写功能,自由分发,放飞自我,大家看怎么样? 求评估,求批评 https://github.com/congzhangzh/desk ...

  5. 如何使用python爬取网页动态数据

    我们在使用python爬取网页数据的时候,会遇到页面的数据是通过js脚本动态加载的情况,这时候我们就得模拟接口请求信息,根据接口返回结果来获取我们想要的数据. 以某电影网站为例:我们要获取到电影名称以 ...

  6. jdk8的安装与环境搭建

    jdk8的安装与环境搭建 jdk8下载网址:https://www.oracle.com/cn/java/technologies/javase/javase-jdk8-downloads.html ...

  7. vscode配置golang开发环境手把手描述篇

    1.下载安装Golang https://golang.google.cn/dl/ 一路下一步即可 2.下载安装Vscode https://visualstudio.microsoft.com/zh ...

  8. [THUPC2019] 找树

    一.题目 点此看题 二.解法 这道题很离谱啊,看上去是求一个最大值,其实是把生成树权值为 \(i\) 的个数都给算出来,因为权值很小. 既然是生成树可以考虑矩阵树定理,我们考虑他是求这样一个式子: \ ...

  9. BuaacodingT141 microhhh的回城 题解(模拟)

    题目链接 microhhh的回城 解题思路 这题挺有意思的.本来寻思放在\(DS\)第一次练习赛应该不会很难吧,结果愣是卡在数据范围上写不出来. 然后暴力过掉了,但是用了\(1019ms\).感觉可以 ...

  10. android分析之mutex

    Android的锁是对Linux锁的一种包装: // ------------------------------------------------------------------------- ...