异步初始化bean

前两天在看 SOFABoot 的时候,看到一个让我眼前一亮的东西,来给大家盘一下。

SOFABoot,你可能不眼熟,但是没关系,本文也不是给你讲这个东西的,你就认为它是 SpringBoot 的变种就行了。

因为有蚂蚁金服背书,所以主要是一些金融类的公司在使用这个框架:

图片

官方介绍是这样的:

SOFABoot 是蚂蚁金服开源的基于 Spring Boot 的研发框架,它在 Spring Boot 的基础上,提供了诸如 Readiness Check,类隔离,日志空间隔离等能力。在增强了 Spring Boot 的同时,SOFABoot 提供了让用户可以在 Spring Boot 中非常方便地使用 SOFA 中间件的能力。

上面这些功能都很强大,但是我主要是分享一下它的这个小功能:

https://help.aliyun.com/document_detail/133162.html

图片

这个功能可以让 Bean 的初始化方法在异步线程里面执行,从而加快 Spring 上下文加载过程,提高应用启动速度。

为什么看到功能的时候,我眼前一亮呢,因为我很久之前写过这篇文章《我是真没想到,这个面试题居然从11年前就开始讨论了,而官方今年才表态。》

里面提到的面试题是这样的:

Spring 在启动期间会做类扫描,以单例模式放入 ioc。但是 spring 只是一个个类进行处理,如果为了加速,我们取消 spring 自带的类扫描功能,用写代码的多线程方式并行进行处理,这种方案可行吗?为什么?

当时通过 issue 找到了官方对于这个问题回复总结起来就是:应该是先找到启动慢的根本原因,而不是把问题甩锅给 Spring。这部分对于 Spring 来说,能不动,就别动。

仅从“启动加速-异步初始化方法”这个标题上来看,Spring 官方不支持的东西 SOFABoot 支持了。所以这玩意让我眼前一亮,我倒要看看你是怎么搞得。

先说结论:SOFABoot 的方案能从一定程度上解决问题,但是它依赖于我们编码的时候指定哪些 Bean 是可以异步初始化的,这样带来的好处是不必考虑循环依赖、依赖注入等等各种复杂的情况了,坏处就是需要程序员自己去识别哪些类是可以异步初始化的。

我倒是觉得,程序员本来就应该具备“识别自己的项目中哪些类是可以异步初始化”的能力。

但是,一旦要求程序员来主动去识别了,就已经“输了”,已经不够惊艳了,在实现难度上就不是一个级别的事情了。人家 Spring 想的可是框架给你全部搞定,顶多给你留一个开关,你开箱即用,啥都不用管。

但是总的来说,作为一次思路演变为源码的学习案例来说,还是很不错的。

我们主要是看实现方案和具体逻辑代码,以 SOFABoot 为抓手,针对其“异步初始化方法”聚焦下钻,把源码当做纽带,协同 Spring,打出一套“我看到了->我会用了->我拿过来->我看懂了->是我的了->写进简历”的组合拳。

Demo

先搞个 Demo 出来,演示一波效果,先让你直观的看到这是个啥玩意。

这个 Demo 非常之简单,几行代码就搞定。

先搞两个 java 类,里面有一个 init 方法:

图片

然后把他们作为 Bean 交给 Spring 管理,Demo 就搭建好了:

图片

直接启动项目,启动时间只需要 1.152s,非常丝滑:

图片

然后,注意,我要稍微的变一下形。

在注入 Bean 的时候触发一下初始化方法,模拟实际项目中在 Bean 的初始化阶段,既在 Spring 项目启动过程中,做一些数据准备、配置拉取等相关操作:

图片

再次重启一下项目,因为需要执行两个 Bean 的初始化动作,各需要 5s 时间,而且是串行执行,所以启动时间直接来到了 11.188s:

图片

那么接下来,就是见证奇迹的时刻了。

我加上 @SofaAsyncInit 这样的一个注解:

图片

你先别管这个注解是哪里来的,从这个注解的名称你也知道它是干啥的:异步执行初始化。

这个时候我再启动项目:

图片

从日志中可以看到:

  1. whyBean 和 maxBean 的 init 方法是由两个不同的线程并行执行的。
  2. 启动时间缩短到了 6.049s。

所以 @SofaAsyncInit 这个注解实现了“指定 Bean 的初始化方法实现异步化”。

你想想,如果你有 10 个 Bean,每个 Bean 都需要 1s 的时间做初始化,总计 10s。

但是这些 Bean 之间其实不需要串行初始化,那么用这个注解,并行只需要 1s,搞定。

到这里,你算是看到了这样的东西存在,属于“我看到了”。

接下来,我们进入到“我会用了”这个环节。

怎么来的。

在解读原理之前,我还得告诉你这个注解到底是怎么来的。

它属于 SOFABoot 框架里面的注解,首先你得把你的 SpringBoot 修改为 SOFABoot。

这一步参照官方文档中的“快速开始”部分,非常的简单:

https://www.sofastack.tech/projects/sofa-boot/quick-start/

第一步就是把项目中 pom.xml 中的:

<parent>
    <groupId>org.springframework.boot</groupId>
    <art

猜你喜欢

转载自blog.csdn.net/mmmmm44444/article/details/132825297
今日推荐