Definition, Registrierung und Erwerb von Bean-Objekten im Frühjahr

1. Einleitung

In Spring umfasst der Prozess des Definierens, Registrierens und Abrufens von Bean-Objekten normalerweise die folgenden zugrunde liegenden Klassen:

  • BeanDefinition: Dies ist eine Schnittstelle, die alle Konfigurationsinformationen einer Bean definiert, einschließlich des Klassennamens der Bean, ob es sich um einen Singleton handelt, des Konstruktors und der Konstruktionsparameter der Bean, der Attribute der Bean usw.
  • DefaultListableBeanFactory: Dies ist die Kernklasse von Spring. Es handelt sich um eine Standard-Bean-Factory und eine Registrierung von Bean-Definitionen. Wir können sie zum Registrieren von Bean-Definitionen verwenden.
  • BeanDefinitionBuilder: Dies ist eine Toolklasse, die zum Erstellen von BeanDefinition verwendet wird.

2. Spezifischer Prozess

Der Definitions-, Registrierungs- und Erfassungsprozess von Bean-Objekten in Spring ist der Kern des Spring IoC-Containers (Inversion of Control). Das Folgende ist der spezifische Ablauf dieses Prozesses:

  • Beans definieren: In Spring werden Beans normalerweise in Spring-Konfigurationsdateien (z. B. XML-Dateien) definiert. Jede Bean verfügt über eine eindeutige ID (oder einen eindeutigen Namen) und einen entsprechenden vollständig qualifizierten Klassennamen sowie andere Konfigurationsmetadaten (z. B. Umfang, Konstruktionsparameter, Eigenschaftswerte usw.).
    Eine Bean-Definition in einer XML-Konfigurationsdatei könnte beispielsweise so aussehen:
<bean id="myBean" class="com.example.MyClass">
    <property name="property1" value="Value1" />
</bean>
  • Bean registrieren: Der Spring IoC-Container ist für das Lesen der Konfigurationsdatei und das Parsen der Bean-Definition verantwortlich. Der Container registriert dann die Bean-Definition in der Bean-Factory (normalerweise DefaultListableBeanFactory), woraufhin jede Bean als BeanDefinition-Objekt dargestellt wird
  • Bean erhalten: Wenn wir eine Bean verwenden müssen, können wir die Bean erhalten, indem wir die getBean-Methode von ApplicationContext aufrufen. Beim Abrufen einer Bean prüft der Spring IoC-Container zunächst, ob die Bean bereits vorhanden ist. Wenn die Bean noch nicht existiert, erstellt der Container eine neue Bean-Instanz basierend auf der BeanDefinition. Während des Erstellungsprozesses einer Bean-Instanz ist Spring für die Handhabung aller Abhängigkeiten (dh Abhängigkeitsinjektion) verantwortlich. Wenn die Bean ein Singleton ist, gibt Spring beim zukünftigen Abrufen der Bean direkt die vorhandene Bean-Instanz zurück.

3. Teilweise Analyse des Kernquellcodes

  • SingletonBeanRegistry

SingletonBeanRegistry ist eine Schnittstelle im Spring-Framework, die hauptsächlich zur Verwaltung der Registrierung von Singleton-Beans verwendet wird. Es bietet einen Mechanismus zum Registrieren vorinstanziierter Objekte (Singleton-Objekte) zur Laufzeit im Spring-Container, die später abgerufen und von anderen Teilen der Anwendung verwendet werden können. Im IoC-Container (Inversion of Control) von Spring wird diese Schnittstelle hauptsächlich zum Verwalten von Objekten verwendet, die nicht vom Container selbst erstellt werden, z. B. von Benutzern manuell erstellte Objekte oder von anderen Frameworks oder Factory-Methoden erstellte Objekte.

public interface SingletonBeanRegistry {
    
    
    // 这个方法用于向注册表中注册一个新的单例Bean。参数beanName是Bean的名称,而singletonObject则是要注册的单例对象。
	void registerSingleton(String beanName, Object singletonObject);
	//根据单例bean的名称获取这个单例bean
	@Nullable
	Object getSingleton(String beanName);
     //判断是不是包含指定名称的单例bean
	boolean containsSingleton(String beanName);
	 //这个方法返回注册表中所有已经注册的单例Bean的名称。返回的是一个字符串数组
	String[] getSingletonNames();
     //这个方法返回注册表中单例bean的数量
	int getSingletonCount();
     //单例模式下带来的最严重的问题就是线程安全问题,
	 //getSingletonMutex() 方法在 SingletonBeanRegistry 接口中返回一个mutex(互斥锁)对象,该对象用于单例Bean的外部同步。
	 // 当你需要自定义的同步逻辑或者在进行某些需要线程安全保障的操作时,你可以使用这个返回的mutex对象来进行同步控制。
	Object getSingletonMutex();

}
  • DefaultSingletonBeanRegistry

Eine sehr wichtige Klasse im Pring-Framework, die hauptsächlich zur Bereitstellung von Caching- und Registrierungsdiensten für Singleton-Beans verwendet wird. Diese Klasse implementiert die SingletonBeanRegistry-Schnittstelle und definiert einige Kernmethoden für die Verwaltung von Singleton-Beans.

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    
    
	//允许保留的警告的最多数量
	private static final int SUPPRESSED_EXCEPTIONS_LIMIT = 100;
	//下面的几个map就是用来存储Bean的容器了,singletonObjects这个是一个ConcurrentHashMap,它是线程安全的,初始容量为256,用于存储已经完全初始化并可以被使用的单例对象。键是bean的名称,值是对应的bean实例
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    //这个Map存储了对象工厂(ObjectFactory),这些工厂负责产生单例对象。当一个单例bean被创建但未初始化时,它将会被存储在这个Map中
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
    //这个Map存储了早期的单例对象,即已经实例化但还未完全初始化(例如,还没有进行属性注入)的bean。这些早期的bean主要用于解决循环依赖的问题(两个或者更多的bean彼此依赖,形成了一个依赖的循环)
	private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
    //这是一个Set,存储了所有已经注册的单例bean的名字,按照注册的顺序排列
	private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
	//这是一个Set,存储了当前正在创建的bean的名字,这主要用于检测bean的循环依赖
	private final Set<String> singletonsCurrentlyInCreation =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));
	//这是一个Set,存储了在创建检查中被排除的bean的名字。这些bean不会被用于循环依赖检查
	private final Set<String> inCreationCheckExclusions =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));
	//这是一个Exception的Set,用于收集在创建单例过程中被忽略的异常
	@Nullable
	private Set<Exception> suppressedExceptions;
	//这是一个布尔值,用于标识当前是否正在销毁单例beans
	private boolean singletonsCurrentlyInDestruction = false;
    //这是一个Map,用于存储所有的DisposableBean实例。DisposableBean是Spring中的一个接口,实现这个接口的bean在容器销毁时会调用其destroy方法,进行清理工作
	private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
    //这是一个Map,存储了包含关系的beans。键是包含其他beans的bean的名称,值是被包含的beans的名称的Set
	private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
    //这是一个Map,存储了依赖关系的beans。键是依赖其他beans的bean的名称,值是被依赖的beans的名称的Set
	private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
	//这是一个Map,存储了依赖关系的beans。键是被依赖的bean的名称,值是依赖这个bean的beans的名称的Set
	private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
	//这个方法用于向注册表中注册一个新的单例 bean。参数 beanName 是 bean 的名称
	@Override
	public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
    
    
		//判断参数是否为空
		Assert.notNull(beanName, "Bean name must not be null");
		Assert.notNull(singletonObject, "Singleton object must not be null");
		//因为是单例,所以操作其时不能有别的线程,所以这里需要加锁
		synchronized (this.singletonObjects) {
    
    
			//这句代码和下面的判断主要是为了判断当前bean的名称是否已经存在了,如果已经存在了就会抛出IllegalStateException异常
			Object oldObject = this.singletonObjects.get(beanName);
			if (oldObject != null) {
    
    
				throw new IllegalStateException("Could not register object [" + singletonObject +
						"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
			}
			//调用addSingleton方法,添加新的bean实例
			addSingleton(beanName, singletonObject);
		}
	}
	//该方法用于添加新的单例bean
	protected void addSingleton(String beanName, Object singletonObject) {
    
    
		synchronized (this.singletonObjects) {
    
    
			//向singletonObjects这个map中添加新的单例的键值对
			this.singletonObjects.put(beanName, singletonObject);
			//singletonFactories保存一个单例bean被创建但未初始,加入到singletonObjects意味着这个单例bean被创建了,所以需要从工厂中移除
			this.singletonFactories.remove(beanName);
			//和上面同样的道理
			this.earlySingletonObjects.remove(beanName);
			//registeredSingletons存储已经被实例化的单例bean的名称,这里将新创建的单例bean的名称保存到set集合中
			this.registeredSingletons.add(beanName);
		}
	}
    //这个方法的作用是添加一个单例工厂
	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    
    
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		//
		synchronized (this.singletonObjects) {
    
    
			//它首先检查singletonObjects这个map中是否已经包含了给定名称的bean。如果已经包含了,那么这个方法就什么都不做,直接返回。
			if (!this.singletonObjects.containsKey(beanName)) {
    
    
				//把给定的singletonFactory添加到singletonFactories这个map中。在这个map中,键是bean的名称,值是对应的ObjectFactory
				this.singletonFactories.put(beanName, singletonFactory);
				//从earlySingletonObjects这个map中移除给定名称的bean。earlySingletonObjects这个map存储了早期的单例对象,即已经实例化但还未完全初始化的bean。这些早期的bean主要用于解决循环依赖的问题
				this.earlySingletonObjects.remove(beanName);
				//把给定的bean的名称添加到registeredSingletons这个set中。registeredSingletons这个set存储了所有已经注册的单例bean的名称
				this.registeredSingletons.add(beanName);
			}
		}
	}
    //重写SingletonBeanRegistry的getSingleton方法,获得指定名称的单例bean
	@Override
	@Nullable
	public Object getSingleton(String beanName) {
    
    
		return getSingleton(beanName, true);
	}
	//主要目的是获取指定名称的单例对象。如果需要,它还会创建这个单例对象的早期引用,这段代码的作用是获取给定bean名称的单例实例。
	// 它首先尝试从singletonObjects映射中获取完全初始化的单例实例。如果无法获取,则检查该bean是否正在创建中,如果是,则尝
	// 试从earlySingletonObjects映射中获取已实例化但未完全初始化的单例实例。如果仍然无法获取,则根据allowEarlyReference
	// 参数的值,决定是否创建早期引用(解决循环依赖问题)。如果允许创建早期引用,则尝试从singletonFactories映射中获取bean工
	// 厂,并使用该工厂创建早期引用。最后,将创建的单例实例存储在singletonObjects或earlySingletonObjects映射中,以便后续使用。
	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    
    
		//尝试从singletonObjects映射(已经完全初始化的单例对象映射)中获取bean实例
		Object singletonObject = this.singletonObjects.get(beanName);
		//如果在singletonObjects中找不到对应的实例,且该bean当前正在创建中(通过isSingletonCurrentlyInCreation(beanName)检查),则进入下一步
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    
    
			//尝试从earlySingletonObjects映射(已实例化但未完全初始化的对象映射)中获取bean实例
			singletonObject = this.earlySingletonObjects.get(beanName);
			//如果在earlySingletonObjects中也找不到,且参数allowEarlyReference为true,表示允许创建早期引用(主要是解决循环依赖问题),则进入下一步
			if (singletonObject == null && allowEarlyReference) {
    
    
				synchronized (this.singletonObjects) {
    
    
					// 在singletonObjects上同步,确保线程安全,然后再次尝试从singletonObjects和earlySingletonObjects映射中获取bean实例
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
    
    
						singletonObject = this.earlySingletonObjects.get(beanName);
						if (singletonObject == null) {
    
    
							//如果以上尝试都未能获取到bean实例,那么尝试从singletonFactories映射(存储bean工厂的映射)中获取对应的bean工厂
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {
    
    
								//如果获取到了bean工厂,就用它来创建bean实例(早期引用),然后将这个早期引用存储在earlySingletonObjects映射中,并从singletonFactories映射中移除对应的bean工厂
								singletonObject = singletonFactory.getObject();
								this.earlySingletonObjects.put(beanName, singletonObject);
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}
	//这个方法可以接受一个名为 singletonFactory 的 ObjectFactory 参数,它的功能主要是获取指定名称的单例对象,如果没有找到,它将使用提供的 ObjectFactory 来创建一个。
	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    
    
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
    
    
			//在已经初始化的单例中查找指定名称的bean
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
    
    
				//如果当前正在销毁单例,这段代码是Spring框架的一个安全机制,用于防止在容器正在销毁单例bean时创建新的单例bean
				//是 Spring Framework 中用于获取单例对象的核心方法之一。它首先在已经初始化的单例对象中查找指定名称的 bean,
				// 如果找到了就直接返回。如果没有找到,则会尝试从指定的工厂中获取实例。在获取实例之前,它会进行循环依赖检查,
				// 并记录是否在单例创建的过程中出现过异常。如果成功获取到了实例,则会将其添加到单例对象池中,并返回该实例。
				// 如果在获取实例的过程中出现了异常,则会将异常记录下来,并抛出 BeanCreationException 异常。
				if (this.singletonsCurrentlyInDestruction) {
    
    
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				if (logger.isDebugEnabled()) {
    
    
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				//循环依赖检查
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				//recordSuppressedExceptions,记录是否在单例创建的过程中出现过异常
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				//如果没有出现过异常,则创建一个新的LinkedHashSet来记录异常
				if (recordSuppressedExceptions) {
    
    
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
    
    
					//尝试从指定的工厂中获取实例
					singletonObject = singletonFactory.getObject();
					//标记是不是新的实例
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
    
    
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
    
    
						throw ex;
					}
				}
				catch (BeanCreationException ex) {
    
    
					if (recordSuppressedExceptions) {
    
    
						for (Exception suppressedException : this.suppressedExceptions) {
    
    
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				}
				finally {
    
    
					if (recordSuppressedExceptions) {
    
    
						this.suppressedExceptions = null;
					}
					//添加到销毁的集合
					afterSingletonCreation(beanName);
				}
				//如果是新的单例对象就添加到
				if (newSingleton) {
    
    
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}
	//向异常集合中添加新的异常
	protected void onSuppressedException(Exception ex) {
    
    
		synchronized (this.singletonObjects) {
    
    
			if (this.suppressedExceptions != null && this.suppressedExceptions.size() < SUPPRESSED_EXCEPTIONS_LIMIT) {
    
    
				this.suppressedExceptions.add(ex);
			}
		}
	}

   //按照单例的名称删除已经被初始化的单例对象
	protected void removeSingleton(String beanName) {
    
    
		synchronized (this.singletonObjects) {
    
    
			this.singletonObjects.remove(beanName);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.remove(beanName);
		}
	}
    //判断是否有存在指定名称的bean
	@Override
	public boolean containsSingleton(String beanName) {
    
    
		return this.singletonObjects.containsKey(beanName);
	}
    //获得所有已经初始化的实例的民初
	@Override
	public String[] getSingletonNames() {
    
    
		synchronized (this.singletonObjects) {
    
    
			return StringUtils.toStringArray(this.registeredSingletons);
		}
	}
	//获得已经初始化的bean的数量
	@Override
	public int getSingletonCount() {
    
    
		synchronized (this.singletonObjects) {
    
    
			return this.registeredSingletons.size();
		}
	}
    //用来设置一个bean是否正在被创建
	public void setCurrentlyInCreation(String beanName, boolean inCreation) {
    
    
		Assert.notNull(beanName, "Bean name must not be null");
		//如果正在创建就加入到inCreationCheckExclusions集合中
		if (!inCreation) {
    
    
			this.inCreationCheckExclusions.add(beanName);
		}
		//如果没有在创建,就从这个集合中删除这个bean(可能这个集合中不存在这个bean的名称)
		else {
    
    
			this.inCreationCheckExclusions.remove(beanName);
		}
	}
    //判断这个bean是否正在被创建
	public boolean isCurrentlyInCreation(String beanName) {
    
    
		Assert.notNull(beanName, "Bean name must not be null");
		return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName));
	}
	protected boolean isActuallyInCreation(String beanName) {
    
    
		return isSingletonCurrentlyInCreation(beanName);
	}
	public boolean isSingletonCurrentlyInCreation(String beanName) {
    
    
		return this.singletonsCurrentlyInCreation.contains(beanName);
	}
	//这段代码的作用是在创建单例bean之前进行检查,以确保没有循环依赖的问题。
	// 如果当前正在创建的单例bean已经在创建过程中,则会抛出一个BeanCurrentlyInCreationException异常。
	// 如果beanName不在inCreationCheckExclusions列表中,则会将其添加到singletonsCurrentlyInCreation集合中,
	// 以便检查循环依赖。
	protected void beforeSingletonCreation(String beanName) {
    
    
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
    
    
			throw new BeanCurrentlyInCreationException(beanName);
		}
	}
    //这段代码是 Spring Framework 中用于在单例对象创建完成之后进行的一些清理工作的方法之一。它会检查当前单例对象是否处于创建状态,如果是,
	// 则将其从单例对象的创建集合中移除。如果单例对象不处于创建状态,则会抛出 IllegalStateException 异常,提示该单例对象并不处于创建状态。
	//在 Spring Framework 中,为了避免循环依赖的问题,它会在创建单例对象之前先将该对象的名称添加到单例对象的创建集合中。在单例对象创建完成之后,
	// 就需要将其从创建集合中移除,以便下一次获取该单例对象时不会再次触发循环依赖检查
	protected void afterSingletonCreation(String beanName) {
    
    
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
    
    
			throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
		}
	}
    //销毁bean的集合
	public void registerDisposableBean(String beanName, DisposableBean bean) {
    
    
		synchronized (this.disposableBeans) {
    
    
			this.disposableBeans.put(beanName, bean);
		}
	}
    //这段代码是 Spring Framework 中用于注册一个 Bean 包含的其他 Bean 的方法之一。它会将被包含的 Bean 的名称和包含它的 Bean 的名称作为参数传入,
	// 然后将被包含的 Bean 的名称添加到包含它的 Bean 的 containedBeanMap 属性中。如果 containedBeanMap 中已经存在该被包含的 Bean,则直接返回,
	// 否则将其添加到 containedBeanMap 中。接着,该方法会调用 registerDependentBean 方法,将被包含的 Bean 和包含它的 Bean 之间建立依赖关系,
	// 以确保在包含它的 Bean 销毁时,被包含的 Bean 也会被销毁。
	public void registerContainedBean(String containedBeanName, String containingBeanName) {
    
    
		synchronized (this.containedBeanMap) {
    
    
			//如果指定的containingBeanName在containedBeanMap中不存砸,就创建一个新的LinkedHashSet,
			//computeIfAbsent 是 Java 8 中 Map 接口新增的方法,它的作用是:如果指定 key 对应的 value 不存在,就使用 mappingFunction 计算出新的 value,
			// 并将其存储到 Map 中。如果指定 key 对应的 value 已经存在,则直接返回该 value,不会再次执行 mappingFunction。
			Set<String> containedBeans =
					this.containedBeanMap.computeIfAbsent(containingBeanName, k -> new LinkedHashSet<>(8));
			if (!containedBeans.add(containedBeanName)) {
    
    
				return;
			}
		}
		registerDependentBean(containedBeanName, containingBeanName);
	}
	public void registerDependentBean(String beanName, String dependentBeanName) {
    
    
		String canonicalName = canonicalName(beanName);

		synchronized (this.dependentBeanMap) {
    
    
			Set<String> dependentBeans =
					this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
			if (!dependentBeans.add(dependentBeanName)) {
    
    
				return;
			}
		}

		synchronized (this.dependenciesForBeanMap) {
    
    
			Set<String> dependenciesForBean =
					this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
			dependenciesForBean.add(canonicalName);
		}
	}

	//判读两个bean是否有依赖关系
	protected boolean isDependent(String beanName, String dependentBeanName) {
    
    
		synchronized (this.dependentBeanMap) {
    
    
			return isDependent(beanName, dependentBeanName, null);
		}
	}

	private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
    
    
		if (alreadySeen != null && alreadySeen.contains(beanName)) {
    
    
			return false;
		}
		String canonicalName = canonicalName(beanName);
		Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
		if (dependentBeans == null) {
    
    
			return false;
		}
		if (dependentBeans.contains(dependentBeanName)) {
    
    
			return true;
		}
		for (String transitiveDependency : dependentBeans) {
    
    
			if (alreadySeen == null) {
    
    
				alreadySeen = new HashSet<>();
			}
			alreadySeen.add(beanName);
			if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
    
    
				return true;
			}
		}
		return false;
	}


	protected boolean hasDependentBean(String beanName) {
    
    
		return this.dependentBeanMap.containsKey(beanName);
	}

	public String[] getDependentBeans(String beanName) {
    
    
		Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
		if (dependentBeans == null) {
    
    
			return new String[0];
		}
		synchronized (this.dependentBeanMap) {
    
    
			return StringUtils.toStringArray(dependentBeans);
		}
	}
	public String[] getDependenciesForBean(String beanName) {
    
    
		Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(beanName);
		if (dependenciesForBean == null) {
    
    
			return new String[0];
		}
		synchronized (this.dependenciesForBeanMap) {
    
    
			return StringUtils.toStringArray(dependenciesForBean);
		}
	}
   //销毁单例bean
	public void destroySingletons() {
    
    
		if (logger.isTraceEnabled()) {
    
    
			logger.trace("Destroying singletons in " + this);
		}
		synchronized (this.singletonObjects) {
    
    
			//用来标记当前正在执行销毁过程,不能再创建新的bean
			this.singletonsCurrentlyInDestruction = true;
		}

		String[] disposableBeanNames;
		synchronized (this.disposableBeans) {
    
    
			//获得当前正在销毁集合中的bean的名称
			disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
		}
		for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
    
    
			//调用销毁方法
			destroySingleton(disposableBeanNames[i]);
		}
        //删除所有的依赖关系
		this.containedBeanMap.clear();
		this.dependentBeanMap.clear();
		this.dependenciesForBeanMap.clear();
		clearSingletonCache();
	}
	protected void clearSingletonCache() {
    
    
		synchronized (this.singletonObjects) {
    
    
			//删除所有的bean存储信息
			this.singletonObjects.clear();
			this.singletonFactories.clear();
			this.earlySingletonObjects.clear();
			this.registeredSingletons.clear();
			this.singletonsCurrentlyInDestruction = false;
		}
	}
	//销毁指定的名称的bean
	public void destroySingleton(String beanName) {
    
    
		// Remove a registered singleton of the given name, if any.
		removeSingleton(beanName);
		// Destroy the corresponding DisposableBean instance.
		DisposableBean disposableBean;
		synchronized (this.disposableBeans) {
    
    
			disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
		}
		destroyBean(beanName, disposableBean);
	}
	//删除该单例的依赖信息
	protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
    
    
		// Trigger destruction of dependent beans first...
		Set<String> dependencies;
		synchronized (this.dependentBeanMap) {
    
    
			// Within full synchronization in order to guarantee a disconnected Set
			dependencies = this.dependentBeanMap.remove(beanName);
		}
		if (dependencies != null) {
    
    
			if (logger.isTraceEnabled()) {
    
    
				logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
			}
			for (String dependentBeanName : dependencies) {
    
    
				destroySingleton(dependentBeanName);
			}
		}

		// Actually destroy the bean now...
		if (bean != null) {
    
    
			try {
    
    
				bean.destroy();
			}
			catch (Throwable ex) {
    
    
				if (logger.isWarnEnabled()) {
    
    
					logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);
				}
			}
		}

		// Trigger destruction of contained beans...
		Set<String> containedBeans;
		synchronized (this.containedBeanMap) {
    
    
			// Within full synchronization in order to guarantee a disconnected Set
			containedBeans = this.containedBeanMap.remove(beanName);
		}
		if (containedBeans != null) {
    
    
			for (String containedBeanName : containedBeans) {
    
    
				destroySingleton(containedBeanName);
			}
		}

		// Remove destroyed bean from other beans' dependencies.
		synchronized (this.dependentBeanMap) {
    
    
			for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
    
    
				Map.Entry<String, Set<String>> entry = it.next();
				Set<String> dependenciesToClean = entry.getValue();
				dependenciesToClean.remove(beanName);
				if (dependenciesToClean.isEmpty()) {
    
    
					it.remove();
				}
			}
		}

		// Remove destroyed bean's prepared dependency information.
		this.dependenciesForBeanMap.remove(beanName);
	}

	/**
	 * Exposes the singleton mutex to subclasses and external collaborators.
	 * <p>Subclasses should synchronize on the given Object if they perform
	 * any sort of extended singleton creation phase. In particular, subclasses
	 * should <i>not</i> have their own mutexes involved in singleton creation,
	 * to avoid the potential for deadlocks in lazy-init situations.
	 */
	@Override
	public final Object getSingletonMutex() {
    
    
		return this.singletonObjects;
	}

}

„Frühe Referenz“ bezieht sich auf ein Bean-Objekt, das instanziiert, aber noch nicht vollständig initialisiert wurde. Im Bean-Lebenszyklus von Spring durchläuft die Bean-Erstellung ungefähr die folgenden Schritte:

  1. Instanziierung: Diese Phase bedeutet, dass der Spring-Container eine Bean-Instanz basierend auf der Bean-Definition erstellt. Diese Instanz wurde noch nicht initialisiert und es wurden auch keine Attributwerte eingefügt.
  2. Füllen von Eigenschaften: In dieser Phase fügt der Spring-Container die Eigenschaftswerte in der Konfigurationsdatei oder die Eigenschaftswerte in den Anmerkungen in die Bean-Instanz ein.
  3. Initialisierung: In dieser Phase ruft der Spring-Container die Initialisierungsmethode in der Bean-Instanz auf, um die Initialisierung der Bean abzuschließen. Diese Stufe kann durch die Implementierung der InitializingBean-Schnittstelle oder die Angabe der init-method-Methode in der Konfigurationsdatei erreicht werden.

Wenn in diesem Prozess die Bean nach der Instanziierung, aber vor der Initialisierung von anderen Beans referenziert wird, handelt es sich um eine frühe Referenz. Frühe Referenzen werden hauptsächlich zur Lösung des Problems zirkulärer Abhängigkeiten verwendet. Angenommen, wir haben zwei Singleton-Beans, A und B, wobei A von B und B von A abhängt. Wenn Spring versucht, A zu erstellen, stellt es fest, dass A von B abhängt, also wendet sich Spring an die Erstellung von B. Wenn es dann B erstellt, stellt es fest, dass B von A abhängt. Wenn zu diesem Zeitpunkt keine frühe Referenz vorhanden ist, fällt es in eine Endlosschleife und kann die Bohne der Schöpfung nicht abschließen. Um dieses Problem zu lösen, führt Spring das Konzept der frühen Referenzen ein. Wenn Spring im obigen Beispiel A erstellt, stellt er fest, dass A von B abhängt, sodass Spring B erstellt. Wenn er B erstellt, stellt er fest, dass B von A abhängt. Zu diesem Zeitpunkt versucht Spring nicht erneut, A zu erstellen , gibt aber direkt A. frühe Zitate zurück. Da die frühe Referenz erstellt wird, bevor die Eigenschaften gefüllt werden, wird die zirkuläre Abhängigkeit unterbrochen, sodass die Bean-Erstellung fortgesetzt werden kann

Im Frühjahr kann der Zerstörungsprozess von Singleton-Bohnen in die folgenden Schritte unterteilt werden:

  1. Rufen Sie die Methode destroy() der Schnittstelle „DisposableBean“ auf: Wenn eine Bean die Schnittstelle „DisposableBean“ implementiert, ruft Spring beim Schließen des Containers automatisch die Methode destroy() der Bean zur Zerstörung auf.
  2. Rufen Sie die mit der Annotation @PreDestroy markierte Methode auf: Wenn eine Bean mit einer Methode markiert ist, die die Annotation @PreDestroy verwendet, ruft Spring die Methode automatisch zur Zerstörung auf, wenn der Container geschlossen wird.
  3. Rufen Sie die durch destroy-method angegebene Methode manuell auf: Wenn das Attribut destroy-method in der Konfigurationsdatei angegeben ist, ruft Spring beim Schließen des Containers automatisch die angegebene Methode zur Zerstörung auf.
  4. Rufen Sie eine benutzerdefinierte Zerstörungsmethode auf: Wenn eine Bean ihre eigene Zerstörungsmethode definiert, ruft Spring diese Methode automatisch zur Zerstörung auf, wenn der Container geschlossen wird. In diesem Fall muss der Methodenname explizit in der Konfigurationsdatei angegeben werden.

Wenn der Container geschlossen ist, führt Spring Zerstörungsvorgänge in der oben genannten Reihenfolge durch, um sicherzustellen, dass die Singleton-Bean korrekt zerstört werden kann. Es ist zu beachten, dass Spring Beans im Prototypbereich nicht zerstört, da ihr Lebenszyklus nicht vom Spring-Container verwaltet wird.

  • AbstractBeanFactory

AbstractBeanFactory ist die abstrakte Implementierungsklasse der BeanFactory-Schnittstelle im Spring Framework. Sie ist eine der Kernkomponenten des Spring IoC-Containers und für die Verwaltung der Logik der Bean-Erstellung, Konfiguration, Abhängigkeitsinjektion und des Lebenszyklus verantwortlich. Im Einzelnen hat AbstractBeanFactory hauptsächlich die folgenden Funktionen:

  1. Bietet Bean-Registrierungs- und Erfassungsfunktionen: AbstractBeanFactory stellt die Methode registerBeanDefinition() zum Registrieren von Bean-Definitionen im IoC-Container und die Methode getBean() zum Abrufen von Bean-Instanzen aus dem Container bereit.
  2. Bietet Bean-Erstellungs- und Initialisierungsfunktionen: AbstractBeanFactory ist für die Erstellung von Bean-Instanzen und die Durchführung einer Reihe von Initialisierungsvorgängen nach der Erstellung verantwortlich, einschließlich Abhängigkeitsinjektion, Aware-Schnittstellenrückrufen, Initialisierungsmethodenaufrufen usw.
  3. Bereitstellung einer Bean-Abhängigkeitsinjektionsfunktion: AbstractBeanFactory ist für die Handhabung von Abhängigkeiten zwischen Beans und die Injektion abhängiger Beans in die Ziel-Bean verantwortlich.
  4. Bietet Funktionen zur Verwaltung des Bean-Lebenszyklus: AbstractBeanFactory ist für die Verwaltung des Bean-Lebenszyklus verantwortlich, einschließlich der Erstellung, Initialisierung, Zerstörung und anderer Prozesse von Beans. Während des Prozesses der Bean-Erstellung und -Zerstörung löst AbstractBeanFactory entsprechende Ereignisse aus, damit andere Komponenten den Bean-Lebenszyklus überwachen und verarbeiten können.
  5. Bietet Such- und Verwaltungsfunktionen für Beans im Container: AbstractBeanFactory bietet eine Reihe von Methoden zum Abfragen und Verwalten von Beans im Container, einschließlich der Suche nach Beans basierend auf Name, Typ, Anmerkung usw. und dem Abrufen von Namen, Typen und anderen Informationen aller Bohnen.

Kurz gesagt, AbstractBeanFactory ist eine der Kernkomponenten des Spring IoC-Containers und bietet eine Reihe von Funktionen zum Verwalten der Bean-Erstellung, -Konfiguration, der Abhängigkeitsinjektion und der Lebenszykluslogik.

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
    
    
   
  @Override
	public Object getBean(String name) throws BeansException {
    
    
		return doGetBean(name, null, null, false);
	}
	@Override
	public Object getBean(String name) throws BeansException {
    
    
		return doGetBean(name, null, null, false);
	}
    //获得指定类型的bean
	@Override
	public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
    
    
		return doGetBean(name, requiredType, null, false);
	}
    //获得指定名称的bean,并提供构造参数(没有创建时可以创建)
	@Override
	public Object getBean(String name, Object... args) throws BeansException {
    
    
		return doGetBean(name, null, args, false);
	}
	public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
			throws BeansException {
    
    

		return doGetBean(name, requiredType, args, false);
	}
	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
    
    
        //在 Spring 中,Bean 名称可以包含特殊字符,比如点号(.)和斜杠(/),这些特殊字符在 Bean 的定义中具有特殊的含义。
		// 为了避免这些特殊字符带来的问题,Spring 使用了一个默认的分隔符(默认为点号),将 Bean 名称中的特殊字符替换成默认分隔符。
		String beanName = transformedBeanName(name);
		Object bean;

		//调用DefaultSingletonBeanRegistry的getSingleton方法,如果是单例就直接获取
		Object sharedInstance = getSingleton(beanName);
		//AbstractBeanFactory
		if (sharedInstance != null && args == null) {
    
    
			//判断是否开启类Trace级别的日志记录
			if (logger.isTraceEnabled()) {
    
    
				//判断该单例对象是否正在创建
				if (isSingletonCurrentlyInCreation(beanName)) {
    
    
					//记录日志(提示该bean是一个早期引用还没被初始化)
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
    
    
					//提示该bean是一个缓冲实例(已经被初始化类)
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			//getObjectForBeanInstance  方法是 AbstractAutowireCapableBeanFactory 类的一个私有方法,
			// 用于从 Bean 实例中获取对应的 Bean 对象。
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		//如果没有找到指定的单例bean对象,此时就需要创建这个bean了
		else {
    
    
			//它首先检查指定名称的Bean单例实例是否正在创建中,如果是,则抛出BeanCurrentlyInCreationException异常。
			// 这是为了避免在Bean实例创建期间发生循环依赖或重复创建的情况
			if (isPrototypeCurrentlyInCreation(beanName)) {
    
    
				throw new BeanCurrentlyInCreationException(beanName);
			}
            //创建创建Bean的父工厂
			BeanFactory parentBeanFactory = getParentBeanFactory();
			//如果父工厂不为空,且工厂中有该Bean
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    
    
				//转换Bean的名称
				String nameToLookup = originalBeanName(name);
				//如果父工厂的类型是AbstractBeanFactory或是其子类
				if (parentBeanFactory instanceof AbstractBeanFactory) {
    
    
					//调用doGetBean方法
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
    
    
					//如果带有参数,就调用带参数的getBean方法
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
    
    
					// 没有参数就会调用默认的getBean的方法
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
    
    
					//如果父类工厂不是AbstractBeanFactory或其子类,就会调用这个工厂的getBean方法
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}
            //标记该bean为已创建,将其添加到已创建bean的集合中,这样可以防止重复创建
			if (!typeCheckOnly) {
    
    
				markBeanAsCreated(beanName);
			}
            //创建一个 StartupStep 实例,这是Spring的新特性,用于监控应用的启动过程,可以帮助我们更好地理解和优化应用的启动过程
			StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
					.tag("beanName", name);
			try {
    
    
				if (requiredType != null) {
    
    
					beanCreation.tag("beanType", requiredType::toString);
				}
				//通过 getMergedLocalBeanDefinition(beanName) 获取Bean的合并后的定义信息,即 RootBeanDefinition
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				//检查获取的 RootBeanDefinition。如果bean定义的信息有问题,比如说定义的类不能被实例化,那么这个方法会抛出异常
				checkMergedBeanDefinition(mbd, beanName, args);
				//获取该beam所依赖的bean
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
    
    
					for (String dep : dependsOn) {
    
    
						//存在循环依赖的问题,抛出异常
						if (isDependent(beanName, dep)) {
    
    
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						//将这些依赖关系注册到依赖管理的数据结构中(通过 registerDependentBean(dep, beanName))
						registerDependentBean(dep, beanName);
						try {
    
    
							//获取Bean
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
    
    
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}
                //判断是不是单例bean
				// Create bean instance.
				if (mbd.isSingleton()) {
    
    
					sharedInstance = getSingleton(beanName, () -> {
    
    
						try {
    
    
							//创建bean
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
    
    
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					//将新创建的单例对象赋值给bean
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
                 //如果是原型作用域
				else if (mbd.isPrototype()) {
    
    
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
    
    
						//beforePrototypeCreation(beanName) 和 afterPrototypeCreation(beanName) 是在Bean创建前后的扩展点,
						// 用于执行一些自定义的逻辑。
						beforePrototypeCreation(beanName);
						//创建原型bean
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
    
    
						afterPrototypeCreation(beanName);
					}
					//将创建的原型bean赋值给bean
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}
                //处理自定义作用域
				else {
    
    
					//获得作用域
					String scopeName = mbd.getScope();
					//判断Scope是否为空
					if (!StringUtils.hasLength(scopeName)) {
    
    
						throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
					}
					//获得作用域的名称
					Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
    
    
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
    
    
						//这个get方法是scope.java中的一个方法,这里用lamda表达式实现了生成该bean的工厂
						Object scopedInstance = scope.get(beanName, () -> {
    
    
							//Bean创建前的扩展电
							beforePrototypeCreation(beanName);
							try {
    
    
								//创建Bean
								return createBean(beanName, mbd, args);
							}
							finally {
    
    
								//Bean创建后的扩展点
								afterPrototypeCreation(beanName);
							}
						});
						//将生成的Bean赋值给bean
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
    
    
						throw new ScopeNotActiveException(beanName, scopeName, ex);
					}
				}
			}
			catch (BeansException ex) {
    
    
				beanCreation.tag("exception", ex.getClass().toString());
				beanCreation.tag("message", String.valueOf(ex.getMessage()));
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
			finally {
    
    
				//标记创建bean完成
				beanCreation.end();
			}
		}
        //这段代码处理的是返回Bean的类型转换。当用户在获取Bean时指定了目标类型,Spring会确保返回的Bean是指定类型或者可以转换为指定类型的实例
		if (requiredType != null && !requiredType.isInstance(bean)) {
    
    
			//检查Bean是否是指定的类型以及用户是有指定了类型
			try {
    
    
				//如果不是指定的类型,则尝试进行类型转换。这是通过 getTypeConverter().convertIfNecessary(bean, requiredType) 方法完成的,
				// 其中 getTypeConverter() 返回Bean工厂使用的类型转换器,convertIfNecessary 尝试将Bean转换为目标类型。
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
    
    
					//如果类型转换成功,返回转换后的Bean。如果转换失败或者转换后的Bean为null,抛出 BeanNotOfRequiredTypeException 异常。
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
    
    
				if (logger.isTraceEnabled()) {
    
    
					logger.trace("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		//返回bean
		return (T) bean;
	}
	//创建Bean的方法是一个抽象方法交给子类实现
     protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException;
	//解析和返回给定的 RootBeanDefinition 的Bean类。在Spring中,Bean类是Bean的实例化和装配的基础,因此需要对其进行解析。
	//将在Spring配置中指定的Bean的类名解析为Java Class对象的过程
	@Nullable
	protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
			throws CannotLoadBeanClassException {
    
    

		try {
    
    
			//通过调用 mbd.hasBeanClass() 来检查 RootBeanDefinition 是否已经有了关联的Bean类
			if (mbd.hasBeanClass()) {
    
    
				return mbd.getBeanClass();
			}
			//如果还没有关联的Bean类,那么就需要解析Bean类。这里有两种情况需要考虑:如果系统中已经启用了安全管理器,那么就需要使用 AccessController.doPrivileged
			// 来解析Bean类,确保在解析过程中能够正确地管理权限;如果没有启用安全管理器,那么就直接解析Bean类,这是通过 doResolveBeanClass(mbd, typesToMatch) 实现的
			if (System.getSecurityManager() != null) {
    
    
				return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
						() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
			}
			else {
    
    

				return doResolveBeanClass(mbd, typesToMatch);
			}
		}
		catch (PrivilegedActionException pae) {
    
    
			ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
		}
		catch (ClassNotFoundException ex) {
    
    
			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
		}
		catch (LinkageError err) {
    
    
			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
		}
	}
    //解析bean类的函数主体
	@Nullable
	private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
			throws ClassNotFoundException {
    
    
         //它获取 Bean 的 ClassLoader,这是用于加载 Bean 类的类加载器。同时,也可能
		ClassLoader beanClassLoader = getBeanClassLoader();
		ClassLoader dynamicLoader = beanClassLoader;
		boolean freshResolve = false;

		if (!ObjectUtils.isEmpty(typesToMatch)) {
    
    
			//获取一个临时的类加载器(如果存在的话),在特定的情况下(如织入场景)可能会用到
			ClassLoader tempClassLoader = getTempClassLoader();
			if (tempClassLoader != null) {
    
    
				dynamicLoader = tempClassLoader;
				freshResolve = true;
				if (tempClassLoader instanceof DecoratingClassLoader) {
    
    
					DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
					for (Class<?> typeToMatch : typesToMatch) {
    
    
						dcl.excludeClass(typeToMatch.getName());
					}
				}
			}
		}
          //获得bean的类名
		String className = mbd.getBeanClassName();
		//如果bean的类名不为空
		if (className != null) {
    
    
			//对bean的类名其进行评估。评估可能涉及到动态解析表达式。如果类名不等于评估的结果(说明类名被动态解析了),并且解析结果是 Class 类型或 String 类型,
			// 那么将返回解析结果的 Class 对象或重新解析类名字符串为 Class 对象。对于其他类型的评估结果,会抛出异常
			Object evaluated = evaluateBeanDefinitionString(className, mbd);
			if (!className.equals(evaluated)) {
    
    
				// A dynamically resolved expression, supported as of 4.2...
				if (evaluated instanceof Class) {
    
    
					return (Class<?>) evaluated;
				}
				else if (evaluated instanceof String) {
    
    
					className = (String) evaluated;
					freshResolve = true;
				}
				else {
    
    
					throw new IllegalStateException("Invalid class name expression result: " + evaluated);
				}
			}
			//如果类名被动态解析了(即,解析结果是 String 类型的类名,而不是原来的类名),代码会尝试用当前的类加载器(可能是临时的类加载器)加载类。如果加载失败,会再尝试用 ClassUtils.forName 方法加载类
			if (freshResolve) {
    
    
				// When resolving against a temporary class loader, exit early in order
				// to avoid storing the resolved Class in the bean definition.
				if (dynamicLoader != null) {
    
    
					try {
    
    
						return dynamicLoader.loadClass(className);
					}
					catch (ClassNotFoundException ex) {
    
    
						if (logger.isTraceEnabled()) {
    
    
							logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
						}
					}
				}
				
				return ClassUtils.forName(className, dynamicLoader);
			}
		}

		// Resolve regularly, caching the result in the BeanDefinition...
		//如果类名没有被动态解析(即,类名等于评估的结果),代码会正常解析类,并将解析结果(即 Class 对象)缓存到 Bean 定义中
		return mbd.resolveBeanClass(beanClassLoader);
	}
}

Die doGetBean-Methode ist eine Kernmethode von AbstractBeanFactory in Spring und wird hauptsächlich zum Abrufen und Erstellen von Bean-Instanzen verwendet. Der Hauptablauf dieser Methode ist wie folgt:

  1. Überprüfen Sie zunächst die vorhandene Singleton-Bean. Wenn sie bereits vorhanden ist, geben Sie sie direkt zurück.
  2. Wenn es nicht vorhanden ist, prüfen Sie, ob die Bean gerade erstellt wird, und geben Sie in diesem Fall das frühere Singleton-Objekt zurück. Dies dient dazu, das Problem der zirkulären Abhängigkeit zu lösen.
  3. Wenn kein Singleton-Objekt erstellt wird, beginnen Sie mit der Erstellung eines neuen Singleton-Objekts. Rufen Sie zunächst die Bean-Definitionsinformationen (BeanDefinition) ab und erstellen Sie dann eine neue Bean-Instanz basierend auf diesen Informationen.
  4. Wenn Sie eine neue Bean-Instanz erstellen, analysieren Sie zuerst die Bean-Klasse, instanziieren Sie dann die Klasse, legen Sie dann die Eigenschaften der Bean fest und rufen Sie schließlich die Initialisierungsmethode der Bean auf.
  5. Nachdem Sie die neue Bean-Instanz erstellt haben, fügen Sie sie dem Singleton-Cache hinzu und kehren Sie zurück.

Die doGetBean-Methode implementiert den gesamten Erstellungsprozess einer Bean, einschließlich Klassenanalyse, Instanziierung, Eigenschaftseinstellung, Initialisierung und anderer Schritte. Darüber hinaus werden auch Singleton- und Prototypmuster sowie Probleme mit zirkulären Abhängigkeiten behandelt.

Das Spring-Framework umfasst die folgenden Hauptschritte beim Parsen von Bean-Klassen:

  1. Ressourcenpositionierung: Dies ist die Anfangsphase der Bean-Definition, die hauptsächlich über die Ressourcenschnittstelle und die ResourceLoader-Schnittstelle implementiert wird. In dieser Phase werden bestimmte Konfigurationsdateien gesucht (z. B. XML-Dateien, Anmerkungskonfiguration, Java-Konfiguration usw.).
  2. Laden der Bean-Definition: Diese Phase wird hauptsächlich über die BeanDefinitionReader-Schnittstelle implementiert. Diese Schnittstelle konvertiert die Bean-Definition in der Ressourcendatei in das interne BeanDefinition-Objekt von Spring. Dieses Objekt enthält verschiedene Metainformationen des Beans, wie z. B. den Namen des Beans, den Klassennamen, den Gültigkeitsbereich, Konstruktorparameter, Attributwerte usw.
  3. Bean-Definition registrieren: Diese Phase wird hauptsächlich über die BeanDefinitionRegistry-Schnittstelle implementiert. Diese Schnittstelle registriert das BeanDefinition-Objekt in der Bean-Factory von Spring. Während des Registrierungsprozesses prüft Spring die Gültigkeit der Bean-Definition und verarbeitet Aliase.
  4. Bean-Klasse auflösen: Diese Phase wird hauptsächlich über die Methode AbstractBeanDefinition.resolveBeanClass() implementiert. Diese Methode versucht, die Bean-Klasse zu analysieren und zu prüfen, ob die Bean-Klasse existiert und zugänglich ist.
  5. Bean-Instanz erstellen: Diese Phase wird hauptsächlich über die Methode AbstractAutowireCapableBeanFactory.createBean() implementiert. Diese Methode erstellt eine Instanz der Bean basierend auf der Bean-Definition und führt dann die Eigenschaftsinjektion und -initialisierung durch.
  6. Bean initialisieren: Diese Phase wird hauptsächlich über die Methode AbstractAutowireCapableBeanFactory.initializeBean() implementiert. Diese Methode ruft die Initialisierungsmethode der Bean auf und führt eine Nachbearbeitung der Bean durch.
  7. Verwendung von Bean: Diese Phase wird hauptsächlich über die Methode BeanFactory.getBean() implementiert. Diese Methode gibt eine Instanz der Bean zur Verwendung durch Anwendungscode zurück.
  • AbstractAutowireCapableBeanFactory

AbstractAutowireCapableBeanFactory ist die Kernklasse im Spring-Framework, die für die Erstellung, Initialisierung, Assemblierung und Verwaltung des Bean-Lebenszyklus verantwortlich ist. Es implementiert die AutowireCapableBeanFactory-Schnittstelle und erbt von AbstractBeanFactory. Zu den wichtigsten Funktionen und Merkmalen gehören:

  1. Bean-Instanzen erstellen: Bietet die Kernlogik zum Erstellen von Bean-Instanzen. Entsprechende Bean-Instanzen können basierend auf den Definitionsinformationen der Bean erstellt werden. Es unterstützt mehrere Möglichkeiten zum Erstellen von Instanzen, z. B. die direkte Verwendung des Java-Reflexionsmechanismus über Factory-Methoden Fabrikbohnen usw. .
  2. Abhängigkeitsinjektion: Sie ist für den Abschluss von Abhängigkeitsinjektionsvorgängen verantwortlich, einschließlich Setter-Injektion und Konstruktor-Injektion.
  3. Bean-Initialisierung: Nachdem die Bean erstellt und die Abhängigkeitsinjektion abgeschlossen wurde, ist sie für den Abschluss der Bean-Initialisierung verantwortlich, z. B. für den Aufruf der Initialisierungsmethode, die Ausführung von BeanPostProcessors usw.
  4. Bean-Zerstörung: Es ist auch für den Bean-Zerstörungsprozess verantwortlich, z. B. für den Aufruf der Zerstörungsmethode, die Ausführung der DisposibleBean-Schnittstelle usw.
  5. Verarbeitungs-Bean-Bereich: Verarbeitung von Beans in verschiedenen Bereichen wie Prototype, Singleton, Request, Session, Global usw.
  6. Automatische Assemblierung der Bean: Die automatische Assemblierung kann basierend auf dem Typ oder Namen der Bean durchgeführt werden.
  7. Typkonvertierung: Bei der Abhängigkeitsinjektion können erforderliche Typkonvertierungsvorgänge durchgeführt werden.
  8. Umgang mit zirkulären Abhängigkeiten: Bei der Abhängigkeitsinjektion kann das Problem zirkulärer Abhängigkeiten behandelt werden
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {
    
    
		@Override
	@SuppressWarnings("unchecked")
	public <T> T createBean(Class<T> beanClass) throws BeansException {
    
    
		//这行代码创建了一个新的 RootBeanDefinition 对象,该对象描述了Bean的定义。这是通过传入的类(beanClass)作为参数创建的
		RootBeanDefinition bd = new RootBeanDefinition(beanClass);
		//这行代码将Bean定义的作用域设置为原型
		bd.setScope(SCOPE_PROTOTYPE);
		//这行代码检查给定的类是否安全地缓存在共享的可扩展类加载器上。如果是,则允许缓存该Bean的元数据
		bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader());
		return (T) createBean(beanClass.getName(), bd, null);
	}
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
    
    
        //是否开启了Trace级别的日志
		if (logger.isTraceEnabled()) {
    
    
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		//创建RooteBenaDefinition对象mbdToduse
		RootBeanDefinition mbdToUse = mbd;

		//用来解析类名(这是父类AbstractBeanFactory中实现的方法)它尝试解析给定的类名并返回 Class 对象
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    
    
			//如果 mbd(Bean 定义)还没有类对象,并且 mbd 的类名不为 null,则创建一个新的 RootBeanDefinition 对象,并设置其类
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}
        //准备方法覆盖
		//这一步调用 mbdToUse 的 prepareMethodOverrides 方法,用于验证和准备覆盖的方法。如果验证失败,则抛出一个异常
		try {
    
    
			//prepareMethodOverrides 是 RootBeanDefinition 的一个方法,主要用于处理和验证 Bean 定义中的方法覆盖(method overrides)设置。
			// 这个设置主要用于在 Spring IoC 容器中覆盖或者替换 Spring 管理的 Bean 中的某个方法的行为,这样在后续创建 Bean 实例时,就可以根据这些设置来确定方法的行为。
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
    
    
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
    
    
			//在实例化 Bean 之前,给 BeanPostProcessors 一个机会返回一个代理实例而不是目标 Bean 实例。如果这个步骤返回的 Bean 不为 null,那么就直接返回这个 Bean。如果在这个步骤出现异常,则抛出一个异常
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
    
    
				return bean;
			}
		}
		catch (Throwable ex) {
    
    
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
    
    
			//这里开始创建真正的bean实例
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
    
    
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
    
    
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
    
    
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}
	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
    
    
		//在Spring框架中,BeanWrapper接口是用于处理Bean属性的主要接口。BeanWrapper的作用是设置和获取属性值(单个或批量),获取属性描述符,以及查询设置属性值的能力。
		//BeanWrapper扩展了 PropertyAccessor,这是所有Spring的属性访问器实现的基本接口,包括 BeanWrapper。 BeanWrapper 也提供了分析和管理的方法,以处理嵌套的路径和类型转换。
		//当创建一个新的Bean实例并对其进行填充(例如,从XML配置文件中读取的属性值)时,Spring使用 BeanWrapper。同样,当Spring需要读取或修改现有Bean实例的属性时,也会使用 BeanWrapper。
		BeanWrapper instanceWrapper = null;
		//判断RootbeanDefinition对象的类型
		if (mbd.isSingleton()) {
    
    
            //factoryBeanInstanceCache这个集合中,一个bean的名称对应一个BeanWrapper,如果是当例模式我们就删除这对映射关系
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		//表示不是单例模式
		if (instanceWrapper == null) {
    
    
			// 使用 createBeanInstance 方法实例化 Bean。这个过程可能会调用构造函数或工厂方法,或者在特殊情况下,例如对于 FactoryBean 或者通过 CGLIB 创建的 Bean,可能会使用特定的实例化策略
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		//由BeanWrapper获得Bean对象
		Object bean = instanceWrapper.getWrappedInstance();
		//获得该bean的类型(即对应的class对象)
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
    
    
			mbd.resolvedTargetType = beanType;
		}

		//用于在应用程序上下文中创建bean时执行后处理程序。具体来说,它确保应用所有合并的bean定义的后处理程序,并且只在第一次创建bean时执行。如果在后处理程序期间发生异常,则会抛出BeanCreationException
		synchronized (mbd.postProcessingLock) {
    
    
			//这段代码的作用是确保在创建应用程序上下文中的bean时,应用所有合并的bean定义的后处理程序,并且只在第一次创建bean时执行。如果在后处理程序期间发生异常,则会抛出BeanCreationException
			if (!mbd.postProcessed) {
    
    
				try {
    
    
					//调用applyMergedBeanDefinitionPostProcessors方法,该方法用于应用所有已注册的MergedBeanDefinitionPostProcessor对象,
					// 以修改BeanDefinition对象的属性值
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
    
    
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				//将BeanDefinition对象的postProcessed属性设置为true,表示已经完成了所有的后处理操作。
				mbd.postProcessed = true;
			}
		}
        //检查BeanDefinition对象的isSingleton方法是否返回true,检查是否允许循环引用,以及检查当前单例对象是否正在创建中
		// 用于检查是否允许在创建Bean对象时提前曝光一个单例对象
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
    
    
			if (logger.isTraceEnabled()) {
    
    
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			//将当前对象添加到一个单例工厂
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		//初始化bean实例
		Object exposedObject = bean;
		try {
    
    
			//调用 populateBean 方法,该方法用于填充 Bean 的属性值。
			populateBean(beanName, mbd, instanceWrapper);
			//调用 initializeBean 方法,该方法用于初始化 Bean,并返回一个可公开的 Bean 对象
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
    
    
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
    
    
				throw (BeanCreationException) ex;
			}
			else {
    
    
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}
        //检查是够需要提前暴露单例bean,以避免循环引用问题
		if (earlySingletonExposure) {
    
    
			//根据bean的名称获得这个单例bean
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
    
    
				if (exposedObject == bean) {
    
    //如果 Bean 实例是集合 BeanWrapper 获得的,则将其替换为提前暴露的单例 Bean 实例(类型检查)
					exposedObject = earlySingletonReference;
				}
				//这段代码的作用是在检查循环依赖时,如果某个 Bean 的依赖中存在“原始”版本的 Bean,则抛出异常。具体来说,它会检查当前 Bean 是否存在依赖关系,
				// 如果存在,则遍历依赖关系中的每个 Bean,如果该 Bean 不是仅用于类型检查,则将其添加到 actualDependentBeans 集合中。如果 actualDependentBeans 
				// 不为空,则抛出 BeanCurrentlyInCreationException 异常,该异常表示当前 Bean 正在创建过程中,但其依赖的其他 Bean 已经使用了它的“原始”版本,
				// 而不是最终版本。这通常是类型匹配过于“热切”的结果,可以通过关闭 allowEagerInit 标志来解决。
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
    
    
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					//遍历每一依赖的bean
					for (String dependentBean : dependentBeans) {
    
    
						//如果一个单例 Bean 只是为了类型检查而被创建,就从单例缓存中移除该 Bean。
						//在 Spring 容器中,当一个 Bean 的依赖被注入时,Spring 会检查这些依赖的类型是否匹配。如果依赖的类型不匹配,Spring 会抛出异常。
						// 为了避免这种情况,Spring 会在创建 Bean 实例之前,先创建一个“原型” Bean 实例,用来检查依赖的类型是否正确。如果类型匹配,再创
						// 建真正的 Bean 实例。这个“原型” Bean 实例就是为了类型检查而被创建的。
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
    
    
							// actualDependentBeans.add(dependentBean) 的作用是将dependentBean添加到 
							// `actualDependentBeans`  集合中。在这段代码中,它的作用是将当前 Bean 的依赖中不是仅用于
							// 类型检查的 Bean 添加到  `actualDependentBeans`  集合中,以便后续判断是否存在循环依赖。
							actualDependentBeans.add(dependentBean);
						}
					}
					//"类型匹配过于热切" 是指在 Spring 容器中,当容器在创建 Bean 的时候,会尝试去匹配该 Bean 所依赖的其他 Bean 的类型。
					// 如果匹配成功,就会将这些依赖注入到该 Bean 中。但是有时候,容器会过于热切地去匹配这些依赖,导致匹配出来的 Bean 并不
					// 是最终的 Bean 实例,而是用于类型检查的“原型” Bean 实例。这样就可能会导致循环依赖等问题。因此,建议在使用类型匹配时,
					// 要谨慎使用,避免出现这种情况。
					if (!actualDependentBeans.isEmpty()) {
    
    
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
    
    
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
    
    
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}
	@Override
	public int getBeanDefinitionCount() {
    
    
		return this.beanDefinitionMap.size();
	}

}

BeanPostProcessor ist eine sehr wichtige Funktionsschnittstelle im Spring-Framework. Sie ermöglicht uns die Durchführung zusätzlicher Verarbeitungsvorgänge, nachdem der Spring IoC-Container die Bean instanziiert hat. Die BeanPostProcessor-Schnittstelle definiert zwei Methoden: postProcessBeforeInitialization und postProcessAfterInitialization.

  • postProcessBeforeInitialization: Diese Methode wird ausgeführt, bevor eine Bean-Initialisierungsmethode (z. B. InitializingBean.afterPropertiesSet oder eine benutzerdefinierte Init-Methode) aufgerufen wird. Mit dieser Methode können wir eine zusätzliche Verarbeitung der Bean durchführen.
  • postProcessAfterInitialization: Diese Methode wird ausgeführt, nachdem alle Bean-Initialisierungsmethoden aufgerufen wurden. Mit dieser Methode können wir eine Nachbearbeitung durchführen.
    BeanPostProcessor wird in Spring häufig verwendet. Viele wichtige Spring-Funktionen wie AOP, Anmerkungsverarbeitung usw. werden über BeanPostProcessor implementiert.

Die doCreateBean-Methode ist die zugrunde liegende Methode zum Erstellen von Beans im Spring Framework. Es handelt sich um eine Methode in der Klasse AbstractAutowireCapableBeanFactory und wird zum Erstellen und Initialisieren einer Bean-Instanz verwendet. Bevor eine Bean-Instanz erstellt wird, ruft sie die Methode „resolveBeforeInstantiation“ auf, um die Vorgänge aufzulösen, die verarbeitet werden müssen, bevor die Bean instanziiert wird. Anschließend verwendet es die Methode „createBeanInstance“, um eine neue Bean-Instanz zu erstellen, und die Methode „applyMergedBeanDefinitionPostProcessors“, um die zusammengeführten Postprozessoren von BeanDefinition anzuwenden. Als Nächstes werden die Eigenschaftswerte der Bean mit der Methode „populateBean“ gefüllt und mit der Methode „initializeBean“ die Bean initialisiert. Schließlich registriert es die Bean beim Container und gibt eine öffentliche Bean-Instanz zurück. Daher ist die doCreateBean-Methode eine der Kernmethoden zum Erstellen von Beans im Spring Framework.

  • DefaultListableBeanFactory

Die Hauptfunktionen von DefaultListableBeanFactory sind wie folgt:

  • Beans erstellen und verwalten: DefaultListableBeanFactory kann für die Erstellung, Initialisierung und Konfiguration neuer Bean-Instanzen verantwortlich sein.
  • Verwaltung des Bean-Lebenszyklus: DefaultListableBeanFactory kann den gesamten Lebenszyklus von Beans verwalten, einschließlich der Erstellung, Initialisierung, Einstellung und Zerstörung von Beans.
  • Bean-Abhängigkeitsinjektion: DefaultListableBeanFactory unterstützt die Bean-Abhängigkeitsinjektion, das heißt, es kann automatisch andere erforderliche Beans in eine Bean injizieren.
  • Bean-Suche und -Aufzählung: DefaultListableBeanFactory bietet die Möglichkeit, alle Beans zu finden und aufzulisten.

Registrierung und Deregistrierung von Bean-Definitionen: Durch die Implementierung der BeanDefinitionRegistry-Schnittstelle kann DefaultListableBeanFactory auch neue Bean-Definitionen registrieren und vorhandene Bean-Definitionen löschen.

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    
    
		//将bean的名称以及对应的BeanDefinition关联起来的集合
		private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
		
		public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {
    
    

		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");
        //判断beanDefinition的类型是不是AbstractBeanDefinition
		if (beanDefinition instanceof AbstractBeanDefinition) {
    
    
			try {
    
    
				/**
				 * validate方法是AbstractBeanDefinition的一个方法,它用于验证bean定义的内容是否有效。具体来说,它会检查如下几个方面:
				 * 1. bean的类名是否已经设置,或者至少factory bean的名称和工厂方法已经设置
				 * 2. 如果bean是单例,那么它不能同时是抽象的和lazy-init的
				 * 3. bean的方法覆盖是否有效
				 * 4. 如果bean有父bean,那么父bean必须已经存在
				 * 5. 其他一些基本的合法性检查
				 */
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
    
    
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}
        //查看当前的bean是否已经存在beanDefinition了
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
    
    
			//isAllowBeanDefinitionOverriding方法是DefaultListableBeanFactory类的一个方法,它返回一个布尔值,用来判断是否允许覆盖同名的Bean定义。
			//如果isAllowBeanDefinitionOverriding返回true,那么可以用新的Bean定义覆盖旧的Bean定义。
			//如果返回false,则不允许覆盖。如果尝试覆盖,将抛出BeanDefinitionOverrideException异常。
			if (!isAllowBeanDefinitionOverriding()) {
    
    
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
			//现在已经存在的beanDefinition的role和新的beanDefinition的定义
			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
    
    
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (logger.isInfoEnabled()) {
    
    
					logger.info("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							existingDefinition + "] with [" + beanDefinition + "]");
				}
			}
			else if (!beanDefinition.equals(existingDefinition)) {
    
    
				if (logger.isDebugEnabled()) {
    
    
					logger.debug("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			else {
    
    
				if (logger.isTraceEnabled()) {
    
    
					logger.trace("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			//将新的beanDefinition加入到beanDefinitionMap中,替换到原来的定义
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		//如果当前的集合中不存在指定bean名称的BeanDefinition
		else {
    
    
			//用于检查当前 BeanFactory 是否已经开始创建bean
			if (hasBeanCreationStarted()) {
    
    
				synchronized (this.beanDefinitionMap) {
    
    
					//将新的BeanDefinition添加到map中
					this.beanDefinitionMap.put(beanName, beanDefinition);
					//BeadDefinition的数量+1
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					//将原来的beanDefinition的名称都添加到新的集合
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					//在 Spring 中,通常情况下,Bean 的创建和注册是由 Spring 容器自动完成的。但在某些情况下,你可能需要手动创建和注册 Bean。比如,
					// 在编程式地使用 Spring 容器时,或者在需要动态地创建和注册 Bean 时。
					//
					//当你手动注册了一个单例 Bean 时,Spring 容器会把这个 Bean 的名称添加到一个特定的列表中,这个列表用于存储所有手动注册的单例
					// Bean 的名称。removeManualSingletonName 方法就是用于从这个列表中移除指定的 Bean 名称
					removeManualSingletonName(beanName);
					//这样做的原因主要是考虑到线程安全性和不可变性。在多线程环境下,如果有多个线程同时读写 beanDefinitionNames 列表,那么可能会出现数据不一致的情况。
					// 为了避免这种情况,我们在修改列表之前,先创建一个新的列表,然后再进行修改。修改完成之后,再将新的列表赋值给 beanDefinitionNames。这样可以保证
					// 在任何时刻,其他线程看到的 beanDefinitionNames 列表都是一个完整且一致的列表,而不会出现中间状态。
				}
			}
			else {
    
    
				// Still in startup registration phase
				this.beanDefinitionMap.put(beanName, beanDefinition);
				this.beanDefinitionNames.add(beanName);
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}
        //如果新的beanDefinition是一个单例
		if (existingDefinition != null || containsSingleton(beanName)) {
    
    
			//resetBeanDefinition 方法是 Spring DefaultListableBeanFactory 类中的一个方法,
			// 主要功能是清除 Bean 定义缓存,以及所有关联的 Bean 的相关信息
			resetBeanDefinition(beanName);
		}
		else if (isConfigurationFrozen()) {
    
    
			clearByTypeCache();
		}
	}

Im Spring-Framework ist die Rolle einer Bean ein Konzept, das die Rolle oder Verantwortung einer Bean in einer Anwendung angibt. Konkret definiert die BeanDefinition-Schnittstelle drei Rollen:

  1. ROLE_APPLICATION: Diese Art von Bean ist normalerweise die Bean der obersten Ebene in der Anwendung und spielt eine zentrale Rolle in der Geschäftslogik. Bei diesen Bohnen handelt es sich normalerweise um Bohnen, die wir selbst definieren und schreiben. (Der entsprechende konstante Wert ist 0)
  2. ROLE_SUPPORT: Dieser Bean-Typ wird normalerweise für bestimmte interne Rollen verwendet und ist nicht Teil der Geschäftslogik. Beispielsweise können Beans erstellt werden, um eine bestimmte Infrastrukturfunktion oder einen Dienst auf Systemebene zu implementieren. (Der entsprechende konstante Wert ist 1)
  3. ROLE_INFRASTRUCTURE: Beans dieses Typs werden vollständig intern von Spring verwendet und sind normalerweise Teil des Spring-Frameworks selbst. Diese Beans sind für Benutzer des Spring-Frameworks transparent und müssen diese Beans nicht direkt verwenden.
    Das Konzept dieser Rolle wird hauptsächlich verwendet, um eine Möglichkeit zur Klassifizierung von Bohnen bereitzustellen. Bei großen Spring-Anwendungen kann das Verständnis der Rolle von Bohnen dazu beitragen, Bohnen besser zu verstehen und zu verwalten. Beim Schreiben von Code müssen wir dieses Konzept jedoch normalerweise nicht direkt verwenden, da die Beans, die wir selbst schreiben, in den meisten Fällen vom Typ ROLE_APPLICATION sind. (Der entsprechende konstante Wert ist 2)

Supongo que te gusta

Origin blog.csdn.net/qq_43456605/article/details/131065296
Recomendado
Clasificación