什么是SpringBean
官方解释
In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container.
fanyi.baidu.com后
- 在Spring中,构成应用程序主干,并由SpringIoC容器管理的对象称为bean,bean是一个由SpringIoC容器实例化、组装和管理的对象
bean是一个 由SpringIoC容器实例化、组装和管理的 对象
SpringBean 是线程安全的吗?
不是,本身容器本身就没有提供线程安全的保障
如果想要解决的话
- 可以使用bean的prototype(bean的作用域)来进行简单的处理
Spring Bean的生命周期
重要: 序号列(1、2、3)则是SpringBean的创建流程
- 实例化(createBeanInstance())
- refresh()
- freshBeanFactoryInanlzation
- preInstantiateSingletons
- getSingletionCache (获取单例缓存中是否存在bean)
- getBean(获取)
- doCreateBean (创建)
- createBeanInstance
- 解释流程
- 1. 进行对bean进行初始化到sing三级缓存中
- 属性赋值(populateBean())
- and 三级缓存的中的第二个Param中的lamdba
- 解释流程
- 2. 进行poptfactoty进行属性赋值流程
- 1. 如果存在内嵌注入,则循环实例被注入的实例,被放入二级缓存中
- 2. 进行poptfactoty进行属性赋值流程
- 初始化 (initializeBean())
- initializeBean()
- 解释流程
- 3. 继续赋值到bean,讲完整对象放入一级缓存中
- 销毁(Destruction)
Spring Bean的作用域
- singleton 唯一的bean实例,SpringBean的实例默认都是单例的
- prototype 每调用一次就生成一次实例
- request 每次的http请求都会创建一个新的实例,(仅对于request使用)
- sesssion 每次的http请求都会创建一个新的实例 (仅对于session使用)
Spring如何解决循环依赖
- 首先我们先要去清楚什么情况下会发生循环依赖
- 1. 使用 构造方法进行使用实例对象时会发生循环依赖
- 2. 使用 @Scope("protutype") 造成循环后,每次都是创建新的实例进行使用,也就造成了循环依赖
- 为什么构造方法和prototype的情况下会造成循环依赖 cycle
- 问题1: 构造方法为什么会造成;如何解决
- 因为在进行实例化后,进行属性复制的时候,a - (属性注入)-> b - (属性注入)-> c ,最后a拿到的是b的地址 c拿到的是a的地址,它们三个都是实例化未初始化的阶段,所以在进行初始化阶段的时候,也就产生了循环依赖
- ps:Spring的初始化干了些什么
- 完成bean内的属性赋值,等等
- 如何解决
- 1. 取消构造参数注入,我们在注入的时候,使用@Autowired,对值进行注入
- 为啥???
- 在进行注入的时候,我们a也就已经完成了populateBean()的操作,也完成了初始化,这是我们拿到的是 propety 类型的B,以此类推
- 为啥???
- 2. 使用aop进行解决
- 这里面涉及了 Singleton一二三级缓存的使用情况
- 1. 取消构造参数注入,我们在注入的时候,使用@Autowired,对值进行注入
- 问题二 prototype作用bean时怎么也就出现了循环依赖,如何解决?
- prototypr已经不是单例的了,很简单,每次都会创建一个新的实例,A的头 永远获取不到 ~
- 解决:
- 使用单例bean
- 问题1: 构造方法为什么会造成;如何解决
Spring Singleton一二三级缓存分别存放什么对象
- 一级缓存
- 完整对象(已经完成属性赋值的bean对象)
- 二级缓存(Spring循环依赖的问题也就涉及到 二级缓存 就解决了)
- 半完整对象
- 三级缓存
- 实例化对象,待属性赋值的
一般去getSingleton时都会去 一级缓存中去拿,相同的bean一级缓存存在后,根据生命周期 也就会直接remove掉