Bean的加载过程
Spring中的一切对象都被IoC容器托管,对象是合适加载,如何加载,什么时候销毁的呢。
Spring中Bean的生命周期
需要注意的地方:
BeanNameAware
接口,需要实现setBeanName(String s)
方法,Spring将bean的id传过来,一般没啥作用;BeanFactoryAware
接口,实现setBeanFactory(BeanFactory beanFactory)
方法,spring传递的容器工厂实例;ApplicationContextAwaer
接口,实现setApplicationContext(ApplicationContext applicationContext)
接口,传递过来的是应用上下文;BeanPostProcess
接口,实现postProcessBeforeInitialization
和postProcessAfterInitialization
,bean初始化之前和之后的处理;InitializingBean
接口,实现afterPropertiesSet
,全部属性设置完成后执行;- 使用后,如果bean实现了
DispostbleBean
接口,那么销毁的时候会执行destory方法。
如何解决循环依赖
spring在创建A的时候,发现需要依赖B,因为去创建B实例,发现B又依赖于A,又去创建A,因为形成一个闭环,无法停止下来就可能会导致cpu计算飙升。
spring解决这个问题主要靠巧妙的三层缓存,所谓的缓存主要是指这三个map,singletonObjects主要存放的是单例对象,属于第一级缓存;
singletonFactories属于单例工厂对象,属于第三级缓存;earlySingletonObjects属于第二级缓存,如何理解early这个标识呢?它表示只是经过了实例化尚未初始化的对象。
Spring首先从singletonObjects(一级缓存)中尝试获取,如果获取不到并且对象在创建中,则尝试从earlySingletonObjects(二级缓存)中获取,如果还是获取不到并且允许从singletonFactories通过getObject获取,则通过singletonFactory.getObject()(三级缓存)获取。
如果获取到了则移除对应的singletonFactory,将singletonObject放入到earlySingletonObjects,其实就是将三级缓存提升到二级缓存,这个就是缓存升级。
spring在进行对象创建的时候,会依次从一级、二级、三级缓存中寻找对象,如果找到直接返回。由于是初次创建,只能从第三级缓存中找到(实例化阶段放入进去的),创建完实例,然后将缓存放到第一级缓存中。下次循环依赖的再直接从一级缓存中就可以拿到实例对象了。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 张国丰!
评论