Get a singleton bean from the cache

The singleton will only be created once in the same container of spring, and then the bean will be obtained directly from the singleton cache. Of course, it is just trying to load, first try to load from the cache, and then try to load from the singletonFactories again. Because there will be dependency injection when creating a singleton, and in order to avoid circular dependencies when creating dependencies, spring's principle of creating beans is that the ObjectFactory that creates the bean will be exposed to the cache in advance before the bean is created. Once the next bean is created and needs to depend on the previous bean, the ObjectFactory is used directly.

public Object getSingleton(String beanName) {
		return getSingleton(beanName, true);
	}
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);
	}

This method confuses readers because it involves the detection of circular dependencies and record access involving many variables. This method first tries to get the instance from singletonObjects. If it can't get it, then get it from earlySingletonObjects. If it can't get it, try to get the ObjectFactory corresponding to beanName from singletonFactories, and then call the getObject of this ObjectFactory to create a bean and put it in the Go to earlySingletonObjects, and remove the ObjectFactory from singletonFactories, and all subsequent memory operations are only used for circular dependency detection, that is, only when allowEarlyReference is true.

This involves different maps for storing beans:

  • singletonObjects: used to save the relationship between the BeanName and the creation of the bean instance
  • singletonFactories: used to hold the relationship between the BeanName and the factory that created the bean
  • earlySingletonObjects: It also saves the relationship between BeanName and the creation of bean instances. The difference from singletonObjects is that when a singleton bean is placed here, then when the bean is still in the process of being created, it can be obtained through the getBean method. , whose purpose is to detect circular references
  • registeredSingletons: used to save all currently registered beans

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325840845&siteId=291194637