曹工说Spring Boot源码系列开讲了(1)-- Bean Definition到底是什么,附spring思维导图分享 写在前面的话&&About me
网上写spring的文章多如牛毛,为什么还要写呢,因为,很简单,那是人家写的;网上都鼓励你不要造轮子,为什么你还要造呢,因为,那不是你造的。
我不是要造spring,我只是想把自己学习spring的一些感想,一些心得说出来,希望大家看到有不对的地方,一定不吝赐教。
说说我自己,13年小本毕业,软件工程专业,校招去了最近疯传的牢厂总部里待了2年,15年越狱出来,某落魄互联网公司(PC时代风头无两)待了1年,慨叹深圳买房之艰难,遂于16年底回蓉。趁着热血未冷,去了一家创业公司,9个月后,欠薪3月,靠刷信用卡还贷,不得不含泪辞职;17年投奔国企,目前从事公共安全相关工作,趁着对技术还有一腔热情,没事写写文章,目前主要兴趣是:分布式、微服务等后端技术;对k8s等新技术保持关注;没事参加一些线下技术活动,欢迎大家和我交流。
本系列的源码讲解思路本来,我是想分享一些 spring cloud 的东西,但后来发现,我自己在读spring cloud的过程中,有些东西也不是理解得很透彻,比如各种@Enable注解其实是用到了spring boot的东西,然后我觉得应该倒回去先看看spring boot,然后呢,看spring boot的过程中,发现spring 和 spring boot其实是一个深度融合,“你中有我,我中有你”的关系,比如spring boot启动时,不是会连带启动spring 容器吗,等等。
我就想着,干脆把spring boot系统研究一把算了,我在github上找了spring boot的工程,克隆到了码云上(速度要快得多),然后自己回退到了spring boot的第一个版本,时间大概是2013年4月,其实这第一个版本,基本的代码也已经成型了,我就拿这个版本的源码在本地idea里面看,配套的spring 版本是4.0.0,也还行。
我自己加了不少注释在工程里,工程地址在这:
https://gitee.com/ckl111/spring-boot-first-version-learn
工程结构如下:
这个工程我也会一直维护着,我觉得,spring 4.0.0的版本,暂时对我阅读代码来说,足够了,如果大家大概了解spring 每个版本的新特性的话,可以发现,spring 4.0开始,各种注解已经很完善了,现在虽然已经出到5.2版本了,但核心的东西也还是没有变化,所以,对我们研读源码,影响不大。如果真的把这个版本能读得差不多了,那想必对spring /spring boot的核心也理解差不多了,到时候再读新版本的源码也不迟,是吧。
总体来说:
spring boot 版本,2013年4月,first version。
配套的spring版本,4.0.0.BOOTSTRAP-SNAPSHOT
那时候的spring boot长什么样子,我这边给个地址(我这已经克隆到码云了)
https://gitee.com/ckl111/spring-boot/tree/fb6b2244707dd5dfad12d62cb6a3c396555270d1/
spring思维导图(bean definition部分)因为我这个系列,大概会按照思维导图的流程来走,然后思维导图太大了,我这里先直接贴前面这部分:
思维导图完整链接:https://www.processon.com/view/link/5deeefdee4b0e2c298aa5596
我大概的讲解思路也会是上面那样,从上到下,每个点细细地讲。
正文 bean definition是什么闲言少叙,进入正题。第一讲,先说说bean definition吧,这个东西,实在太重要了,核心的存储结构啊。
大家可以再想一想,spring 当初刚出来的时候,主打的是ioc容器,容器里装了啥呢,bean啊!bean是什么呢?
恩。。。我也不知道是啥,反正spring里拿出来的就是bean。
行,那bean有什么特征吗?
哦,bean是一个对象,有名字,有class类型,有scope(单例、prototype那些),有role(属于应用的bean、还是spring框架的bean),有是否延迟初始化(lazy-init),有它依赖的其他bean,如果这个bean不好造(不能直接反射生成的话),可能还有个工厂方法和工厂bean呢,哎,好像还说漏了,反正挺多的。
那是不是每个bean都有这些属性呢?
仔细想想,好像是的吧。
既然都有这些东西,那这个东西感觉像是个模板了,就像是最近写了年终总结,hr小姐姐就给我们发了模板,上面姓名啊、部门啊、职位啊、述职的基本格式啊,都是固定的,我们只要拿来,填上自己的信息就行了,那我们是不是可以抽象一下,搞个class啊,比如下面这样:
package com.learn; import lombok.Data; @Data public class SpringDefinition { /** * bean class名 */ String beanClassName; /** * 工厂bean的名称 */ String factoryBeanName; /** * 工厂方法的名称 */ String factoryMethodName; /** * singleton/prototype等 */ String scope; /** * 是否延迟初始化 */ boolean isLazyInit; /** * 依赖的bean */ String[] dependsOn; /** * bean的角色,比如:1:框架;2:应用 */ int role; /** * 是否为主候选bean */ boolean primary; ...其他属性 }