时间:2022-05-07 09:11:08 | 栏目:JAVA代码 | 点击:次

对象创建
对象销毁
spring 支持 5 种作用域,如下:
request:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。
什么是循环依赖
一个AService里面引用了BService的一个对象,BService里面又引用了AService的一个对象。
那么在构造AService的bean的时候,会填充属性以及注入依赖,那么就需要注入BService的bean,spring发现BService的bean还没有创建,又会去构造BService的bean。同理BService的bean又需要AService的bean,这时候因为AService的bean还没有构建好,所以他也会去创建AService的bean。一直循环

怎么解决:使用二级缓存

有什么问题
如果上述的bean不存在AOP,那么是没有什么问题的,但是如果存在AOP的话,那么构造出来的bean对象就不是原始对象了,而是AOP生成的代理对象。如果还是使用二级缓存的话,那么B从缓存取的是A的原始对象而不是构造好的A的bean对象
怎么解决
添加一层缓存,singletonFactories:第三级缓存,里面存放的是要被实例化的对象的对象工厂。
主要代码如下:
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
分析getSingleton()的整个过程,Spring首先从一级缓存singletonObjects中获取。如果获取不到,并且对象正在创建中,就再从二级缓存earlySingletonObjects中获取。如果还是获取不到且允许singletonFactories通过getObject()获取,就从三级缓存singletonFactory.getObject()(三级缓存)获取,如果获取到了则从singletonFactories中移除,并放入earlySingletonObjects中。其实也就是从三级缓存移动到了二级缓存。
总结一下流程: