spring和springBoot

手撕springBoot源码

1、什么是spring

要说springBoot就不得不提一下spring,我理解的spring就是,是一个整合框架,是一个容器。他有两大特点IOC和AOP
ioc就是控制反转,简单点来说就是将创建对象的权利从我们自己变成了spring容器。
aop 暂时没太理解
那么是如何控制反转可以主动创建对象的呢?
让我们简单的回顾一下一个Java Bean在spring中是如何通过控制反转创建的吧
1、解析配置文件或者注解内容 通过BeanDefinitionReader读取配置信息 生成一个个BeanDefinition对象(生成bean的说明书)
2、然后通过BeanDefinitionRegistry 将每一个BeanDefinition对象和特定的id绑定在一起,存到一个map中去。(将bean的说明书先存起来)
3、第一个拓展点来了,通过BeanFactoryPostProcessor,对BeanDefinition对象做一些修改和替换,比如当时的配置文件引用的是其他配置文件里的值,就会在此做替换。(修补更改说明书的机会)
4、createBeanInstance 通过反射实例化对象。(搭bean骨架)
5、自定义属性 赋值 populateBean(按装轮子和车灯之类的)
6、容器对象属性赋值 检查aware接口(安装车的logo)???
7、又一个拓展 bean对象的扩展–对象前置处理BeanPostProcessor的ProcessBeforeInitialization()方法(出厂前的一些改造)
8、执行初始化方法 invokeInitMethods检测是实现了initializingBean接口,并执行afterPropertiesSet方法,里面可以做一些逻辑实现。(出厂时的一些改造)
9、又一个拓展 bean对象的扩展–对象后置处理BeanPostProcessor的ProcessAfterInitialization()方法(出厂后的一些改造)
10、使用对象
11、销毁对象

Spring的三级缓存

在Spring的依赖注入中,如果有一个对象A的一个属性值是对象B,而对象B的一个属性又是对象A,那么就会造成循环依赖的问题,spring框架为了解决循环依赖,引入了三个由map组成的缓存来解决这个问题
三级缓存流程图
源码代码走读:

//刷新容器
org.springframework.context.support.AbstractApplicationContext#refresh
//开始初始化bean们
org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
//准备初始化
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
//获取bean(先获取A对象)
org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
//获取bean的实际处理逻辑:容器/缓存中是否有,有就直接返回,没有就开始创建
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
{
//从容器/缓存中判断是否有beanA
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)
}
//创建bean对象A
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
//创建bean对象的实际处理逻辑
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean(){
//实例化bean对象A
 instanceWrapper = this.createBeanInstance(beanName, mbd, args);
 //将对象名A和获取半成品对象A的lambda表达式放入三级缓存中
 this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
            });
  //实例化对象开始,填充属性          
 this.populateBean(beanName, mbd, instanceWrapper);
}
//填充属性         
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
//获取属性对应的value值(此时的value值是引用类型的b)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues
//处理value值如有需要,此时的value值是引用类型的b,所以需要处理
org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveValueIfNecessary
//处理引用vaule值(此时的value值是引用类型的b)
org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveReference

//获取bean(此时获取B对象),循环由此开始...
org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
//获取bean的实际处理逻辑:容器/缓存中是否有,有就直接返回,没有就开始创建
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
{
//从容器/缓存中判断是否有beanB,此时没有的对象B
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)
}
//创建bean对象B
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
//创建bean对象的实际处理逻辑
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean(){
//实例化bean对象B
 instanceWrapper = this.createBeanInstance(beanName, mbd, args);
 //将对象名和获取半成品对象的lambda表达式放入三级缓存中
 this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
            });
  //实例化对象开始,填充属性          
 this.populateBean(beanName, mbd, instanceWrapper);
}
//填充属性         
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
//获取属性对应的value值(此时的value值是引用类型的a)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues
//处理value值如有需要,此时的value值是引用类型的a,所以需要处理
org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveValueIfNecessary
//处理引用vaule值
org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveReference
//获取A对象去跟B赋值
org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
//获取bean的实际处理逻辑:容器/缓存中是否有,有就直接返回,没有就开始创建,此时三级缓存有值
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
//(核心代码)从缓存中获取bean,处理逻辑大概就是先从1级缓存中看是否有,没有去二级缓存中拿,二级缓存也没有,去三级缓存中拿,此时三级缓存有,取出三级缓存中的lambda表达式,并运行表达式获取到半成品的A,后面将半成品的A放到二级缓存中,删除三级缓存中的lambda表达式
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
后面的逻辑就是返回半成品A,并把它填充到B的属性中去,然后B对象完全创建完成并将B对象保存到一级缓存中去。
并将完成品B返回给填充A属性那段,完成填充属性,A也创建完成,并将A也储存到1级缓存中去,至此A的整个创建流程结束。
由于我们的配置文件中是两个对象,所以还会去走创建B的流程,但是在1级缓存中有B,所以在getBean的时候就直接返回了。




  • 14
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值