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:
Solutions
Simply put, is the first instance of an object A
is saved to a collection, and then fill properties, examples of his dependent objects B
, if the dependent objects B
are also dependent A
, to an instance of the collection at this time to find out if there is A
found to have A
the will to take out , give B
the filling properties, and then B to complete, and then B
also filled, A
but 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.
Some of the key methods
This method will be called after the instance is created, that is, you want to ObjectFactory
save to singletonFactories
the collection, the next call can be taken out getObject
to 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);//添加到已注册
}
}
}
ObjectFactory
It was written lambda
expressions.
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 ObjectFactory
acquired, calls getObject
the method can get in front of dependent objects into them. A
Created, put singletonFactories
in, rely on B
, B
to create and then rely on A
, this time time to get from A can singletonFactories
get 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.