Spring高级之BeanFactory功能

news2024/12/23 1:17:28

             首先,我们想要知道一个接口有哪些功能,就必须要看这个接口的源代码,在idea中,选中这个接口Ctrl+F12,来查看这个接口里面有哪些方法:

          

 表面上来看,功能其实很少,查看源码及其方法功能

package org.springframework.beans.factory;
import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;

public interface BeanFactory {
	
    // factoryBean 的转义标识符。
	String FACTORY_BEAN_PREFIX = "&";
	
    // 根据 name 从容器中拿对应的 bean。
	Object getBean(String name) throws BeansException;
	
    // 根据 name 和 type 从容器中拿对应的 bean,要对 bean 的类型做校验。
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;
	
    // 在容器中能否找到与 name 匹配的 bean 或者 beanDefinition。
	boolean containsBean(String name);

	// 判断 name 对对应的 bean 是不是 单例。
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
	
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
	// 判断 name 对应的 bean 与指定的类型是否匹配。
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws 
     NoSuchBeanDefinitionException;

	boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws 
       NoSuchBeanDefinitionException;

	//根据 name 获取对应的 bean 的类型。
	@Nullable
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;

    // 根据 name 获取对应 bean 的 别名。
	String[] getAliases(String name);
}

          BeanFactory表面上来看只有 getBean有点用,实际上我们不能只光看它接口,还要看它的实现类,实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能,都由它的实现类提供

  • HierarchicalBeanFactory:提供父容器的访问功能
  • ListableBeanFactory:提供了批量获取Bean的方法
  • AutowireCapableBeanFactory:在BeanFactory基础上实现对已存在实例的管理
  • ConfigurableBeanFactory:主要单例bean的注册,生成实例,以及统计单例bean
  • ConfigurableListableBeanFactory:继承了上述的所有接口,增加了其他功能:比如类加载器,类型转化,属性编辑器,BeanPostProcessor,作用域,bean定义,处理bean依赖关系, bean如何销毁…
  • 实现类DefaultListableBeanFactory:实现了ConfigurableListableBeanFactory,注册BeanDefinition,实现上述BeanFactory所有功能

来看一下DefaultListableBeanFactory的继承关系图:

 

           可以看到,BeanFactory只是它实现的很少一部分,除了BeanFactory提供的getBean,还有其他方法,所以我们不能光看一个接口,还要看它的具体实现类

在这里我们就只看它的DefaultSingletonBeanRegistry接口中的单例对象,这个为大家比较熟悉的,来看源码:

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

	/** Maximum number of suppressed exceptions to preserve. */
	/**
	 * 抑制异常数量最大值
	 */
	private static final int SUPPRESSED_EXCEPTIONS_LIMIT = 100;


	/** Cache of singleton objects: bean name to bean instance. */
	/**
	 * 一级缓存 这个就是我们大名鼎鼎的单例缓存池 用于保存我们所有的单实例bean
	 */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	/** Cache of singleton factories: bean name to ObjectFactory. */
	/**
	 * 三级缓存 该map用户缓存 key为 beanName  value 为ObjectFactory(包装为早期对象)
	 */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

	/** Cache of early singleton objects: bean name to bean instance. */
	/**
	 * 二级缓存 ,用户缓存我们的key为beanName value是我们的早期对象(对象属性还没有来得及进行赋值)
	 */
	private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

	/** Set of registered singletons, containing the bean names in registration order. */
	/**
	 * 已注册的单例名称set
	 */
	private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

	/** Names of beans that are currently in creation. */
	/**
	 * 该集合用于缓存当前正在创建bean的名称
	 */
	private final Set<String> singletonsCurrentlyInCreation =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));

	/** Names of beans currently excluded from in creation checks. */
	/**
	 * 排除当前创建检查的
	 */
	private final Set<String> inCreationCheckExclusions =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));

	/**
	 * Collection of suppressed Exceptions, available for associating related causes.
	 */
	@Nullable
	/**抑制异常的集合,可用于关联相关原因*/
	private Set<Exception> suppressedExceptions;

	/** Flag that indicates whether we're currently within destroySingletons. */
	/**
	 * 指示我们当前是否在 destroySingletons 中的标志。
	 */
	private boolean singletonsCurrentlyInDestruction = false;

	/** Disposable bean instances: bean name to disposable instance. */
	/**
	 * 用于缓存记录实现了DisposableBean 接口的实例
	 */
	private final Map<String, Object> disposableBeans = new LinkedHashMap<>();

	/** Map between containing bean names: bean name to Set of bean names that the bean contains. */
	/**
	 * 缓存bean的属性关系的映射<service,<aDao,bDa>>
	 */
	private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);

	/** Map between dependent bean names: bean name to Set of dependent bean names. */
	/**
	 * 保存的是依赖 beanName 之间的映射关系:beanName - > 依赖 beanName 的集合
	 */
	private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

	/** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */
	/**
	 * 保存的是依赖 beanName 之间的映射关系:依赖 beanName - > beanName 的集合
	 */
	private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

	/**
	 * 注册单例Bean
	 *
	 * @param beanName        the name of the bean
	 * @param singletonObject the existing singleton object
	 * @throws IllegalStateException
	 */
	@Override
	public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
		//断言beanName是否为空
		Assert.notNull(beanName, "Bean name must not be null");
		//断言singletonObject是否为空
		Assert.notNull(singletonObject, "Singleton object must not be null");
		synchronized (this.singletonObjects) {
			//从一级缓存中通过beanName拿取Bean
			Object oldObject = this.singletonObjects.get(beanName);
			//一级缓存中存在了,抛出IllegalStateException
			if (oldObject != null) {
				throw new IllegalStateException("Could not register object [" + singletonObject +
						"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
			}
			//如果不存在,将singletonObject添加到一级缓存
			addSingleton(beanName, singletonObject);
		}
	}

	/**
	 * Add the given singleton object to the singleton cache of this factory.
	 * <p>To be called for eager registration of singletons.
	 * 把对象加入到单例缓存池中(所谓的一级缓存 并且考虑循环依赖和正常情况下,移除二三级缓存)
	 *
	 * @param beanName        the name of the bean
	 * @param singletonObject the singleton object
	 */
	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			//将singletonObject添加到一级缓存中,同时移除二级、三级缓存、并标记当前Bean已注册
			this.singletonObjects.put(beanName, singletonObject);
			//移除三级缓存
			this.singletonFactories.remove(beanName);
			//移除二级缓存
			this.earlySingletonObjects.remove(beanName);
			//标记当前Bean已被注册
			this.registeredSingletons.add(beanName);
		}
	}

	/**
	 * 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.
	 * 该方法用于把早期对象包装成一个ObjectFactory 暴露到三级缓存中 用于将解决循环依赖...
	 *
	 * @param beanName         the name of the bean
	 * @param singletonFactory the factory for the singleton object
	 */
	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		//断言singletonFactory不为空
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		//同步加锁
		synchronized (this.singletonObjects) {
			//单例缓存池中没有包含当前的bean
			if (!this.singletonObjects.containsKey(beanName)) {
				//加入到三级缓存中,,,,,暴露早期对象用于解决循环依赖
				this.singletonFactories.put(beanName, singletonFactory);
				//从二级缓存中移除
				this.earlySingletonObjects.remove(beanName);
				//标记当前Bean已经被注册过
				this.registeredSingletons.add(beanName);
			}
		}
	}

	/**
	 * 该方法是一个空壳方法
	 *
	 * @param beanName the name of the bean to look for
	 * @return 缓存中的对象(有可能是一个单例完整对象, 也有可能是一个早期对象 ( 用于解决循环依赖))
	 */
	@Override
	@Nullable
	public Object getSingleton(String beanName) {
		//在这里 系统一般是允许早期对象引用的 allowEarlyReference通过这个参数可以控制解决循环依赖
		return getSingleton(beanName, true);
	}

	/**
	 * 在网上很多很多写源码的大佬或者是<spring源码深度解析>一书上,也没有说清楚为啥要使用三级缓存(二级缓存可不可以能够
	 * 解决) 答案是:可以, 但是没有很好的扩展性为啥这么说.......
	 * 原因: 获取三级缓存-----getEarlyBeanReference()经过一系列的后置处理来给我们早期对象进行特殊化处理
	 * //从三级缓存中获取包装对象的时候 ,他会经过一次后置处理器的处理对我们早期对象的bean进行
	 * 特殊化处理,但是spring的原生后置处理器没有经过处理,而是留给了我们程序员进行扩展
	 * singletonObject = singletonFactory.getObject();
	 * 把三级缓存移植到二级缓存中
	 * this.earlySingletonObjects.put(beanName, singletonObject);
	 * //删除三级缓存中的之
	 * this.singletonFactories.remove(beanName);
	 *
	 * @param beanName            bean的名称
	 * @param allowEarlyReference 是否允许暴露早期对象  通过该参数可以控制是否能够解决循环依赖的.
	 * @return 这里可能返回一个null(IOC容器加载单实例bean的时候,第一次进来是返回null)
	 * 也有可能返回一个单例对象(IOC容器加载了单实例了,第二次来获取当前的Bean)
	 * 也可能返回一个早期对象(用于解决循环依赖问题)
	 */
	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// Quick check for existing instance without full singleton lock
		/**
		 * 第一步:我们尝试去一级缓存(单例缓存池中去获取对象,一般情况从该map中获取的对象是直接可以使用的)
		 * IOC容器初始化加载单实例bean的时候第一次进来的时候 该map中一般返回空
		 */
		Object singletonObject = this.singletonObjects.get(beanName);
		//如果一级缓存为空,并且标记正在创建
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			/**
			 * 尝试去二级缓存中获取对象(二级缓存中的对象是一个早期对象)
			 * 何为早期对象:就是bean刚刚调用了构造方法,还来不及给bean的属性进行赋值的对象(纯净态)
			 * 就是早期对象
			 */
			singletonObject = this.earlySingletonObjects.get(beanName);
			/**
			 * 二级缓存中也没有获取到对象,allowEarlyReference为true(参数是有上一个方法传递进来的true)
			 */
			if (singletonObject == null && allowEarlyReference) {
				synchronized (this.singletonObjects) {
					// Consistent creation of early reference within full singleton lock
					/**
					 * 再次尝试从一级缓存中去拿,如果还是没拿到则尝试去二级缓存中拿
					 */
					singletonObject = this.singletonObjects.get(beanName);
					//一级缓存中没拿到
					if (singletonObject == null) {
						//尝试从二级缓存中去拿
						singletonObject = this.earlySingletonObjects.get(beanName);
						//二级缓存还是空
						if (singletonObject == null) {
							/**
							 * 直接从三级缓存中获取 ObjectFactory对象 这个对接就是用来解决循环依赖的关键所在
							 * 在ioc后期的过程中,当bean调用了构造方法的时候,把早期对象包裹成一个ObjectFactory
							 * 暴露到三级缓存中
							 */
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							//三级缓存中获取的对象不为空
							if (singletonFactory != null) {
								/**
								 * 在这里通过暴露的ObjectFactory 包装对象中,通过调用他的getObject()来获取我们的早期对象
								 * 在这个环节中会调用到 getEarlyBeanReference()来进行后置处理
								 */
								singletonObject = singletonFactory.getObject();
								//把早期对象放置在二级缓存,
								this.earlySingletonObjects.put(beanName, singletonObject);
								//ObjectFactory 包装对象从三级缓存中删除掉
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		//返回这个Bean
		return singletonObject;
	}

	/**
	 * Return the (raw) singleton object registered under the given name,
	 * creating and registering a new one if none registered yet.
	 * 获取单例对象(该流程用于触发构建bean)
	 *
	 * @param beanName         the name of the bean
	 * @param singletonFactory the ObjectFactory to lazily create the singleton
	 *                         with, if necessary
	 * @return the registered singleton object
	 */
	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		//断言beanName不为空
		Assert.notNull(beanName, "Bean name must not be null");
		//同步加锁
		synchronized (this.singletonObjects) {
			//尝试从一级缓存池中获取对象
			Object singletonObject = this.singletonObjects.get(beanName);
			//从一级缓存中没拿到
			if (singletonObject == null) {
				//当前是否是正在销毁,是的话抛出BeanCreationNotAllowedException异常
				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!)");
				}
				//判断是否已启用Debug调试模式
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				/**
				 * 标记当前的bean马上就要被创建了
				 * singletonsCurrentlyInCreation 在这里会把beanName加入进来,若第二次循环依赖(构造器注入会抛出异常)
				 */
				beforeSingletonCreation(beanName);
				//标记是否为新创建的单例Bean
				boolean newSingleton = false;
				//标记是否记录抑制异常
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				//如果为空,创建抑制异常集合
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}

				try {
					// 初始化 bean
					// 这个过程其实是调用 createBean() 方法
					singletonObject = singletonFactory.getObject();
					//标记这个Bean是新创建的
					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;
					}
					//后置处理
					//主要做的事情就是把singletonsCurrentlyInCreation标记正在创建的bean从集合中移除
					afterSingletonCreation(beanName);
				}
				//是新建的单例Bean,添加到一级缓存中去
				if (newSingleton) {
					addSingleton(beanName, singletonObject);
				}
			}
			//返回单例Bean
			return singletonObject;
		}
	}

	/**
	 * Register an exception that happened to get suppressed during the creation of a
	 * singleton bean instance, e.g. a temporary circular reference resolution problem.
	 * <p>The default implementation preserves any given exception in this registry's
	 * collection of suppressed exceptions, up to a limit of 100 exceptions, adding
	 * them as related causes to an eventual top-level {@link BeanCreationException}.
	 * 注册在创建单例 bean 实例期间碰巧被抑制的异常,例如一个临时的循环引用解析问题。
	 *
	 * @param ex the Exception to register
	 * @see BeanCreationException#getRelatedCauses()
	 */
	protected void onSuppressedException(Exception ex) {
		synchronized (this.singletonObjects) {
			//抑制异常集合不为空,且小于SUPPRESSED_EXCEPTIONS_LIMIT最大限制
			if (this.suppressedExceptions != null && this.suppressedExceptions.size() < SUPPRESSED_EXCEPTIONS_LIMIT) {
				//向抑制集合中添加异常
				this.suppressedExceptions.add(ex);
			}
		}
	}

	/**
	 * Remove the bean with the given name from the singleton cache of this factory,
	 * to be able to clean up eager registration of a singleton if creation failed.
	 * 从该工厂的单例缓存中删除bean ,以便能够在创建失败时清除单例的急切注册。
	 *
	 * @param beanName the name of the bean
	 * @see #getSingletonMutex()
	 */
	protected void removeSingleton(String beanName) {
		//同步加锁
		synchronized (this.singletonObjects) {
			//从一级缓存中移除
			this.singletonObjects.remove(beanName);
			//从三级缓存中移除
			this.singletonFactories.remove(beanName);
			//从二级缓存中移除
			this.earlySingletonObjects.remove(beanName);
			//从Bean注册标记集合中移除
			this.registeredSingletons.remove(beanName);
		}
	}

	/**
	 * 一级缓存中是否存在该Bean
	 *
	 * @param beanName the name of the bean to look for
	 * @return
	 */
	@Override
	public boolean containsSingleton(String beanName) {
		//判断一级缓存中是否存在该Bean
		return this.singletonObjects.containsKey(beanName);
	}

	/**
	 * 获取已注册的单例Bean名字的集合
	 *
	 * @return
	 */
	@Override
	public String[] getSingletonNames() {
		synchronized (this.singletonObjects) {
			//获取已注册的单例Bean名字的集合
			return StringUtils.toStringArray(this.registeredSingletons);
		}
	}

	/**
	 * 获取已注册单例Bean实例的个数
	 *
	 * @return
	 */
	@Override
	public int getSingletonCount() {
		synchronized (this.singletonObjects) {
			//获取已注册单例Bean实例的个数
			return this.registeredSingletons.size();
		}
	}

	/**
	 * 标记当前Bean正在创建,主要解决循环依赖
	 *
	 * @param beanName   Bean名字
	 * @param inCreation 是否已标记
	 */
	public void setCurrentlyInCreation(String beanName, boolean inCreation) {
		//断言Bean不为空
		Assert.notNull(beanName, "Bean name must not be null");
		//如果未标记,将beanName加到inCreationCheckExclusions集合中,已标记则移除
		if (!inCreation) {
			this.inCreationCheckExclusions.add(beanName);
		} else {
			this.inCreationCheckExclusions.remove(beanName);
		}
	}

	/**
	 * 返回当前Bean是否是正在创建
	 *
	 * @param beanName
	 * @return
	 */
	public boolean isCurrentlyInCreation(String beanName) {
		Assert.notNull(beanName, "Bean name must not be null");
		return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName));
	}

	/**
	 * 返回当前Bean实际上是否在创建中
	 *
	 * @param beanName
	 * @return
	 */
	protected boolean isActuallyInCreation(String beanName) {
		return isSingletonCurrentlyInCreation(beanName);
	}

	/**
	 * Return whether the specified singleton bean is currently in creation
	 * (within the entire factory).
	 * 返回指定的单例 bean 当前是否正在创建中
	 *
	 * @param beanName the name of the bean
	 */
	public boolean isSingletonCurrentlyInCreation(String beanName) {
		return this.singletonsCurrentlyInCreation.contains(beanName);
	}

	/**
	 * Callback before singleton creation.
	 * <p>The default implementation register the singleton as currently in creation.
	 * 单例Bean创建前回调方法,默认实现将单例注册为当前正在创建中
	 *
	 * @param beanName the name of the singleton about to be created
	 * @see #isSingletonCurrentlyInCreation
	 */
	protected void beforeSingletonCreation(String beanName) {
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}
	}

	/**
	 * Callback after singleton creation.
	 * <p>The default implementation marks the singleton as not in creation anymore.
	 * 创建单例后回调。 默认实现将单例标记为不再创建。
	 *
	 * @param beanName the name of the singleton that has been created
	 * @see #isSingletonCurrentlyInCreation
	 */
	protected void afterSingletonCreation(String beanName) {
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
			throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
		}
	}


	/**
	 * Add the given bean to the list of disposable beans in this registry.
	 * <p>Disposable beans usually correspond to registered singletons,
	 * matching the bean name but potentially being a different instance
	 * (for example, a DisposableBean adapter for a singleton that does not
	 * naturally implement Spring's DisposableBean interface).
	 * 将给定的 bean 添加到此注册表中的一次性 bean 列表中。 一次性 bean 通常对应于已注册的单例,
	 * 与 bean 名称匹配,但可能是不同的实例(例如,单例的 DisposableBean 适配器不自然实现 Spring 的 DisposableBean 接口)。
	 *
	 * @param beanName the name of the bean
	 * @param bean     the bean instance
	 */
	public void registerDisposableBean(String beanName, DisposableBean bean) {
		synchronized (this.disposableBeans) {
			this.disposableBeans.put(beanName, bean);
		}
	}

	/**
	 * Register a containment relationship between two beans,
	 * e.g. between an inner bean and its containing outer bean.
	 * <p>Also registers the containing bean as dependent on the contained bean
	 * in terms of destruction order.
	 * 注册两个 bean 之间的包含关系,例如在内部 bean 和包含它的外部 bean 之间。还根据销毁顺序将包含的 bean 注册为依赖于所包含的 bean。
	 *
	 * @param containedBeanName  the name of the contained (inner) bean
	 * @param containingBeanName the name of the containing (outer) bean
	 * @see #registerDependentBean
	 */
	public void registerContainedBean(String containedBeanName, String containingBeanName) {
		synchronized (this.containedBeanMap) {
			Set<String> containedBeans =
					this.containedBeanMap.computeIfAbsent(containingBeanName, k -> new LinkedHashSet<>(8));
			if (!containedBeans.add(containedBeanName)) {
				return;
			}
		}
		registerDependentBean(containedBeanName, containingBeanName);
	}

	/**
	 * Register a dependent bean for the given bean,
	 * to be destroyed before the given bean is destroyed.
	 *
	 * @param beanName          the name of the bean
	 * @param dependentBeanName the name of the dependent bean
	 */
	public void registerDependentBean(String beanName, String dependentBeanName) {
		//获取原始的beanName
		String canonicalName = canonicalName(beanName);

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

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

	/**
	 * Determine whether the specified dependent bean has been registered as
	 * dependent on the given bean or on any of its transitive dependencies.
	 * 判断指定的 bean 是否依赖于 dependentBeanName 。
	 *
	 * @param beanName          the name of the bean to check
	 * @param dependentBeanName the name of the dependent bean
	 * @since 4.0
	 */
	//判断指定的 bean 是否依赖于 dependentBeanName
	protected boolean isDependent(String beanName, String dependentBeanName) {
		synchronized (this.dependentBeanMap) {
			return isDependent(beanName, dependentBeanName, null);
		}
	}

	//判断指定的 bean 是否依赖于 dependentBeanName
	private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
		// alreadySeen 已经检测的依赖 bean
		if (alreadySeen != null && alreadySeen.contains(beanName)) {
			return false;
		}
		// 获取原始 beanName
		String canonicalName = canonicalName(beanName);
		//获取创建当前bean 所依赖的bean的名称集合
		Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
		//不依赖任何前置Bean 直接返回
		if (dependentBeans == null) {
			return false;
		}
		// 存在,则证明存在已经注册的依赖
		if (dependentBeans.contains(dependentBeanName)) {
			return true;
		}
		// 递归检测依赖
		for (String transitiveDependency : dependentBeans) {
			if (alreadySeen == null) {
				alreadySeen = new HashSet<>();
			}
			// 添加到 alreadySeen 中
			alreadySeen.add(beanName);
			//递归检查依赖
			if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Determine whether a dependent bean has been registered for the given name.
	 *
	 * @param beanName the name of the bean to check
	 */
	//判断beanName是否注册为依赖Bean
	protected boolean hasDependentBean(String beanName) {
		return this.dependentBeanMap.containsKey(beanName);
	}

	/**
	 * Return the names of all beans which depend on the specified bean, if any.
	 * 返回Bean所依赖的所有Bean集合
	 *
	 * @param beanName the name of the bean
	 * @return the array of dependent bean names, or an empty array if none
	 */
	public String[] getDependentBeans(String beanName) {
		//Bean依赖集合
		Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
		if (dependentBeans == null) {
			return new String[0];
		}
		synchronized (this.dependentBeanMap) {
			return StringUtils.toStringArray(dependentBeans);
		}
	}

	/**
	 * Return the names of all beans that the specified bean depends on, if any.
	 * 返回Bean所依赖的所有Bean集合
	 *
	 * @param beanName the name of the bean
	 * @return the array of names of beans which the bean depends on,
	 * or an empty array if none
	 */
	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) {
			this.singletonsCurrentlyInDestruction = true;
		}

		String[] disposableBeanNames;
		//获取需要销毁的Bean集合
		synchronized (this.disposableBeans) {
			disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
		}
		//循环校徽单例Bean
		for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
			destroySingleton(disposableBeanNames[i]);
		}
		//	清空依赖和映射关系缓存
		this.containedBeanMap.clear();
		this.dependentBeanMap.clear();
		this.dependenciesForBeanMap.clear();

		// 清理Bean的一级二级三级缓存
		clearSingletonCache();
	}

	/**
	 * Clear all cached singleton instances in this registry.
	 * 清除所有缓存的单例实例。
	 *
	 * @since 4.3.15
	 */
	protected void clearSingletonCache() {
		synchronized (this.singletonObjects) {
			this.singletonObjects.clear();
			this.singletonFactories.clear();
			this.earlySingletonObjects.clear();
			this.registeredSingletons.clear();
			this.singletonsCurrentlyInDestruction = false;
		}
	}

	/**
	 * Destroy the given bean. Delegates to {@code destroyBean}
	 * if a corresponding disposable bean instance is found.
	 *
	 * @param beanName the name of the bean
	 * @see #destroyBean
	 */
	public void destroySingleton(String beanName) {
		// Remove a registered singleton of the given name, if any.
		//从缓存中移除当前bean的相关信息,由于不知道在哪里发生异常,所以我们把跟当前bean的所有缓存记录都清除
		removeSingleton(beanName);

		// Destroy the corresponding DisposableBean instance.
		//创建一个变量用于接受 实现了DisposableBean接口的对象变量
		DisposableBean disposableBean;
		synchronized (this.disposableBeans) {
			disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
		}
		//进行bean的销毁
		destroyBean(beanName, disposableBean);
	}

	/**
	 * Destroy the given bean. Must destroy beans that depend on the given
	 * bean before the bean itself. Should not throw any exceptions.
	 * 销毁bean的依赖关系
	 *
	 * @param beanName the name of the bean
	 * @param bean     the bean instance to destroy
	 */
	protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
		// Trigger destruction of dependent beans first...
		// 销毁dependentBeanMap中保存的是当前bean和依赖bean之间的映射
		Set<String> dependencies;
		synchronized (this.dependentBeanMap) {
			// Within full synchronization in order to guarantee a disconnected Set
			//把当前创建dependon 依赖的bean从缓存中移除并且返回处理
			dependencies = this.dependentBeanMap.remove(beanName);
		}
		//如果bean依赖不为空
		if (dependencies != null) {
			if (logger.isTraceEnabled()) {
				logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
			}
			//递归销毁bean
			for (String dependentBeanName : dependencies) {
				destroySingleton(dependentBeanName);
			}
		}

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

		// 删除bean的属性关系的映射
		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.
		//销毁dependentBeanMap 中 Bean的依赖
		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.
		//从dependenciesForBeanMap集合移除
		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;
	}

}

它的方法大多为私有的,可以通过debug和反射,在这里我们通过反射来获取私有的成员变量:

  // DefaultSingletonBeanRegistry类管理所有的单例对象
     //获取所有的私有成员变量
        Field singletonObjects = 
       DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
      //允许可以访问私有成员变量
        singletonObjects.setAccessible(true);
        //通过反射获取
       //获取beanFactory
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
      //反射调用,获取beanFactory的属性
        Map<String, Object> map = (Map<String, Object>) singletonObjects.get(beanFactory);
       //过滤,获取component相关的
        map.entrySet().stream().filter(e -> e.getKey().startsWith("component"))
                .forEach(e -> {
                    System.out.println(e.getKey() + "=" + e.getValue());
                });

总结:

          BeanFactory 能干点啥?

  • 表面上只有 getBean

  • 实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能,都由它的实现类提供

  • 例子中通过反射查看了它的成员变量 singletonObjects,内部包含了所有的单例 bean

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/173739.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

来吧,Jenkins+git+mvn+shell一键部署实践起来

环境&#xff1a;centosJenkins-2.319系统自带gitmvn3.8.7jdk1.8一、安装jdk1、https://blog.csdn.net/codedz/article/details/124044974centos自带了openjdk&#xff0c;我是选择自己重新搞一个&#xff0c;用的上面链接地址的yum安装方式2、安装完成查看版本查看java安装路径…

优思学院|质量人对控制图中的规格线和控制线傻傻分不清?

质量人、六西格玛[1]人和很多不同类型的工程师都需要了解什么是控制图&#xff0c;而在控制图中的规格限制&#xff08;Specification Limit&#xff09;"和"控制限制&#xff08;Control Limit&#xff09;"原来对好多人来说都是傻傻分不清&#xff01; 规格限…

线段树入门

对于一个区间进行询问&#xff0c;进行修改&#xff0c;都是用线段树进行处理。线段树和普通的树不一样&#xff0c;普通的树的节点存的是一个编号&#xff0c;线段树存的是一个区间&#xff0c;而且线段树一定是一棵完全二叉树。例如&#xff1a;这就是一棵线段树。例如对于[1…

【Ajax】数据交换格式XML 和 JSON

一、什么是数据交换格式数据交换格式&#xff0c;就是服务器端与客户端之间进行数据传输与交换的格式。前端领域&#xff0c;经常提及的两种数据交换格式分别是 XML 和 JSON。其中 XML 用的非常少&#xff0c;所以&#xff0c;我们重点要学习的数据交换格式就是 JSON。二、XML1…

让交互更加生动!巧用CSS实现鼠标跟随 3D 旋转效果

简单分析一下&#xff0c;这个交互效果主要有两个核心&#xff1a; 借助了 CSS 3D 的能力 元素的旋转需要和鼠标的移动相结合 本人简单的说一下如何使用纯 CSS 实现类似的交互效果&#xff0c;以及&#xff0c;借助 JavaScript 绑定鼠标事件&#xff0c;快速还原上述效果。 …

数据结构---set篇

第一次超时是因为用memsetmemsetmemset不得不超时&#xff0c;第二次超时是我用vectorvectorvector数组的时候&#xff0c;然后以O(n)O(n)O(n)复杂度查找元素之后使用eraseeraseerase方法进行删除&#xff0c;第三次超时是我把查找元素改成了O(logn)O(logn)O(logn)之后用vector…

epoll的ET和LT模式

简介 epoll对fd的操作有两种模式&#xff1a;LT(Level Trigger&#xff0c;水平触发)模式&#xff0c;和ET&#xff08;Edge Trigger,边缘触发&#xff09;模式。 LT 模式是默认的工作模式&#xff0c;这种模式下&#xff0c;epoll相当于一个效率较高的poll&#xff1b; ET模…

89. 注意力机制以及代码实现Nadaraya-Waston 核回归

1. 心理学 动物需要在复杂环境下有效关注值得注意的点心理学框架&#xff1a;人类根据随意线索和不随意线索选择注意点 随意&#xff1a;随着自己的意识&#xff0c;有点强调主观能动性的意味。 2. 注意力机制 2. 非参注意力池化层 3. Nadaraya-Waston 核回归 4. 参数化的注意…

Downie4.6.4视频下载工具

前言 Downie是Mac下一个简单的下载管理器&#xff0c;可以让您快速将不同的视频网站上的视频下载并保存到电脑磁盘里然后使用您的默认媒体播放器观看它们。 下载 Downie 解压后直接安装 主要特点 支持许多网站目前支持超过1,000个不同的网站&#xff08;包括YouTube&#…

Linux | 浅谈Shell运行原理【王婆竟是资本家】

文章目录&#x1f4a7;Shell的运行原理&#x1f449;Shell的基本概念与作用&#x1f449;原理的展示与剖析&#x1f449;Shell外壳感性理解【一门亲事】&#x1f4a7;总结&#x1f4a7;Shell的运行原理 &#x1f449;Shell的基本概念与作用 Linux严格意义上说的是一个操作系统…

华为数字化转型之道 平台篇 第十三章 变革治理体系

第十三章 变革治理体系 约翰科特在《领导变革》一书中说:“变革的领导团队既需要管理能力,也需要领导能力,他们必须结合起来。 前面我们也谈到,数字化转型不仅是技术的创新,更是一项系统工程和企业真正的变革。企业要转型成功,既需要各个组织的积极参与和通力合作,又不…

深度学习中高斯噪声:为什么以及如何使用

在数学上&#xff0c;高斯噪声是一种通过向输入数据添加均值为零和标准差(σ)的正态分布随机值而产生的噪声。 正态分布&#xff0c;也称为高斯分布&#xff0c;是一种连续概率分布&#xff0c;由其概率密度函数 (PDF) 定义&#xff1a; pdf(x) (1/ (σ*sqrt(2*π))) *e^(- (x…

Task6:文本函数查找函数

文章目录一 文本函数1 Text函数2 mid函数3 replace函数二 查找函数1 Vlookup2 Xlookup一 文本函数 1 Text函数 作用&#xff1a;将数值转换为指定格式的文本 语法&#xff1a;TEXT(value,format_text) &#xff08;1&#xff09;转换为大写 消费日期转换为大写 TEXT(A2,”[DB…

第五届字节跳动青训营 前端进阶学习笔记(六)什么才是好的JavaScript代码

文章目录前言问题引入实现一个交通信号灯的状态切换1.基本实现2.状态封装实现3.职责分离实现求一个数是否是4的幂1.基本实现3.数学优化洗牌算法1.基本实现2.均匀算法实现总结前言 课程重点&#xff1a; 代码规范相关事项如何优化代码 问题引入 试看下面一段代码&#xff0c…

认识UDP、TCP协议

一、Socket 首先&#xff0c;我们需要了解一下socket。 在上一篇文章当中&#xff0c;我们了解了TCP-IP五层协议模型初识网络&#xff1a;IP、端口、网络协议、TCP-IP五层模型_革凡成圣211的博客-CSDN博客TCP/IP五层协议详解https://blog.csdn.net/weixin_56738054/article/det…

Crack:RadiAnt DICOM Viewer 2023.1 BETA #1300

RadiAnt DICOM Viewer 2023.1 BETA #1300 built on January 13, 2023 New features: Length ratio calculation. Ellipsoid / bullet volume calculation. Added option to color and/or pin specific items to top in the DICOM tags window. 多式DICOM的技术支持 该软件能够打…

是时候分享一波jenkins centos的安装了

1、下载注意&#xff1a;至少安装2.319的版本&#xff0c;否则插件安装失败&#xff0c;2.357 之后版本需要java11&#xff0c;请注意java版本a、开始下载&#xff0c;利用华为云地址 https://mirrors.huaweicloud.com/home&#xff0c;速度杠杠快搜索jenkins&#xff0c;点击j…

api接口对接如何实现,php如何对接api

这篇文章来分享下api接口对接如何实现&#xff0c;还有源码&#xff0c;希望对新手有所帮助。 什么是API? 我的回答&#xff1a;API&#xff08; 应用程序编程接口&#xff09;&#xff1a;一般来说&#xff0c;这是一套明确定义的各种软件组件之间的通信方法。 什么是API&…

Android数据库之SharedPreferences、SQLite、Room

文章目录一、SharedPreferences二、SQLite三、Room使用Room进行增删改查Room数据库升级一、SharedPreferences 要想使用SharePreferences来存储数据&#xff0c;首先需要获取到SharedPreferences对象。Android中提供了三种方法用于得到SharedPreferences对象 1.Context类中的g…

20230119英语学习

Back to the Future 在故宫修钟表是种什么样的体验&#xff1f; After a year of complex restoration, specialists from the Palace Museum in Beijing have given a pair of antique pagoda clock automata a new lease on life. In the form of a nine-tiered pagoda, th…