Spring循环依赖

来源:互联网 发布:淘宝内容营销都有哪些 编辑:程序博客网 时间:2024/05/18 10:42

场景 :A依赖B,同时B依赖A,那么Spring在创建Bean是如何防止出现循环加载导致内存溢出的

A ->B

B->A


首先在Spring-beans中的org.springframework.beans.factory.support.DefaultSingletonBeanRegistry 中有如下属性

/** Cache of singleton objects: bean name --> bean instance */private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);/** Cache of singleton factories: bean name --> ObjectFactory */private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);/** Cache of early singleton objects: bean name --> bean instance */private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);/** Set of registered singletons, containing the bean names in registration order */private final Set<String> registeredSingletons = new LinkedHashSet<String>(256);
/** Names of beans that are currently in creation */private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));

Spring在创建A实例时发现通过解析发现依赖B,那么A会通过getSingleton将ObjectFactory放入到earlySingletonObjects中,key是beanNane

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);}

同时将beanName放在singlesCurrentlyInCreation中,由于A依赖B因此此处要先创建B对象,而B对象依赖A,所以B先从singletonsObjects、及缓存中getA对象,若果没有那么将从earlySingletonObjects获得A对应的ObjectFactory对象,接着完成B对象的创建,并将 B对象放在singletonFactories中及缓存中,此时B对象已有,那么开始创建A对象,创建完成后将earlySingletonObjects中对应的beanNane删除,同时将对象放在singletonFactories及缓存中。(这里A、B对象操作流程基本一致,都是先初始化依赖的Bean)

/** * Add the given singleton factory for building the specified singleton * if necessary. * <p>To be called for eager registration of singletons, e.g. to be able to * resolve circular references. * @param beanName the name of the bean * @param singletonFactory the factory for the singleton object */protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(singletonFactory, "Singleton factory must not be null");synchronized (this.singletonObjects) {if (!this.singletonObjects.containsKey(beanName)) {this.singletonFactories.put(beanName, singletonFactory);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}}

重点说明:

A : A与B中的A是不是同一个对象?

Q : 一定是同一对象,因为他们最终都是指向同一个ObjectFactory对象地址



1 0
原创粉丝点击