Spring 5.x Source trip thirty-four getBean circular dependency Solutions

Spring 5.x Source trip thirty-four getBean solve a single case of circular dependencies

Circular dependencies flowchart solution

Look under the circular dependency is a flow chart of how to solve, Lite:

Here Insert Picture Description

Solutions

Simply put, is the first instance of an object Ais saved to a collection, and then fill properties, examples of his dependent objects B, if the dependent objects Bare also dependent A, to an instance of the collection at this time to find out if there is Afound to have Athe will to take out , give Bthe filling properties, and then B to complete, and then Balso filled, Abut also complete. In fact, the principle is very simple, is to find a place to put it, to avoid other dependencies, have taken out to depend on them.
Here Insert Picture Description

Some of the key methods

This method will be called after the instance is created, that is, you want to ObjectFactorysave to singletonFactoriesthe collection, the next call can be taken out getObjectto get instance.

	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);//添加到已注册
			}
		}
	}

ObjectFactoryIt was written lambdaexpressions.
Here Insert Picture Description

getEarlyBeanReference

Internal actually processed by the processor, can be extended, internal processor will not do, if they want changes made before the property can be filled in here to do, but there are ways to extend the processor before filling properties.

	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				}
			}
		}
		return exposedObject;
	}

getSingleton

The key here is to solve circular references, if it is being created, it can be ObjectFactoryacquired, calls getObjectthe method can get in front of dependent objects into them. ACreated, put singletonFactoriesin, rely on B, Bto create and then rely on A, this time time to get from A can singletonFactoriesget in, and then rely on are filled with resolve circular dependencies.

@Nullable
	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);//从singletonFactories获取出来,放进去
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}

Well, here today, we hope to help study and understand, do not spray the Great God see, understand only their own learning, limited capacity, please excuse.

Published 235 original articles · won praise 74 · views 30000 +

Guess you like

Origin blog.csdn.net/wangwei19871103/article/details/105165501