Spring?BeanFactory工廠使用教程
首先,我們想要知道一個(gè)接口有哪些功能,就必須要看這個(gè)接口的源代碼,在idea中,選中這個(gè)接口Ctrl+F12,來查看這個(gè)接口里面有哪些方法:

表面上來看,功能其實(shí)很少,查看源碼及其方法、功能
package org.springframework.beans.factory;
import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
public interface BeanFactory {
// factoryBean 的轉(zhuǎn)義標(biāo)識(shí)符。
String FACTORY_BEAN_PREFIX = "&";
// 根據(jù) name 從容器中拿對(duì)應(yīng)的 bean。
Object getBean(String name) throws BeansException;
// 根據(jù) name 和 type 從容器中拿對(duì)應(yīng)的 bean,要對(duì) bean 的類型做校驗(yàn)。
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
// 在容器中能否找到與 name 匹配的 bean 或者 beanDefinition。
boolean containsBean(String name);
// 判斷 name 對(duì)對(duì)應(yīng)的 bean 是不是 單例。
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
// 判斷 name 對(duì)應(yīng)的 bean 與指定的類型是否匹配。
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws
NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws
NoSuchBeanDefinitionException;
//根據(jù) name 獲取對(duì)應(yīng)的 bean 的類型。
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
// 根據(jù) name 獲取對(duì)應(yīng) bean 的 別名。
String[] getAliases(String name);
}BeanFactory表面上來看只有 getBean有點(diǎn)用,實(shí)際上我們不能只光看它接口,還要看它的實(shí)現(xiàn)類,實(shí)際上控制反轉(zhuǎn)、基本的依賴注入、直至 Bean 的生命周期的各種功能,都由它的實(shí)現(xiàn)類提供
- HierarchicalBeanFactory:提供父容器的訪問功能
- ListableBeanFactory:提供了批量獲取Bean的方法
- AutowireCapableBeanFactory:在BeanFactory基礎(chǔ)上實(shí)現(xiàn)對(duì)已存在實(shí)例的管理
- ConfigurableBeanFactory:主要單例bean的注冊(cè),生成實(shí)例,以及統(tǒng)計(jì)單例bean
- ConfigurableListableBeanFactory:繼承了上述的所有接口,增加了其他功能:比如類加載器,類型轉(zhuǎn)化,屬性編輯器,BeanPostProcessor,作用域,bean定義,處理bean依賴關(guān)系, bean如何銷毀…
- 實(shí)現(xiàn)類DefaultListableBeanFactory:實(shí)現(xiàn)了ConfigurableListableBeanFactory,注冊(cè)BeanDefinition,實(shí)現(xiàn)上述BeanFactory所有功能
來看一下DefaultListableBeanFactory的繼承關(guān)系圖:

可以看到,BeanFactory只是它實(shí)現(xiàn)的很少一部分,除了BeanFactory提供的getBean,還有其他方法,所以我們不能光看一個(gè)接口,還要看它的具體實(shí)現(xiàn)類
在這里我們就只看它的DefaultSingletonBeanRegistry接口中的單例對(duì)象,這個(gè)為大家比較熟悉的,來看源碼:
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/** Maximum number of suppressed exceptions to preserve. */
/**
* 抑制異常數(shù)量最大值
*/
private static final int SUPPRESSED_EXCEPTIONS_LIMIT = 100;
/** Cache of singleton objects: bean name to bean instance. */
/**
* 一級(jí)緩存 這個(gè)就是我們大名鼎鼎的單例緩存池 用于保存我們所有的單實(shí)例bean
*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name to ObjectFactory. */
/**
* 三級(jí)緩存 該map用戶緩存 key為 beanName value 為ObjectFactory(包裝為早期對(duì)象)
*/
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name to bean instance. */
/**
* 二級(jí)緩存 ,用戶緩存我們的key為beanName value是我們的早期對(duì)象(對(duì)象屬性還沒有來得及進(jìn)行賦值)
*/
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
/** Set of registered singletons, containing the bean names in registration order. */
/**
* 已注冊(cè)的單例名稱set
*/
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
/** Names of beans that are currently in creation. */
/**
* 該集合用于緩存當(dāng)前正在創(chuàng)建bean的名稱
*/
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/** Names of beans currently excluded from in creation checks. */
/**
* 排除當(dāng)前創(chuàng)建檢查的
*/
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/**
* Collection of suppressed Exceptions, available for associating related causes.
*/
@Nullable
/**抑制異常的集合,可用于關(guān)聯(lián)相關(guān)原因*/
private Set<Exception> suppressedExceptions;
/** Flag that indicates whether we're currently within destroySingletons. */
/**
* 指示我們當(dāng)前是否在 destroySingletons 中的標(biāo)志。
*/
private boolean singletonsCurrentlyInDestruction = false;
/** Disposable bean instances: bean name to disposable instance. */
/**
* 用于緩存記錄實(shí)現(xiàn)了DisposableBean 接口的實(shí)例
*/
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的屬性關(guān)系的映射<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 之間的映射關(guān)系: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 之間的映射關(guān)系:依賴 beanName - > beanName 的集合
*/
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
/**
* 注冊(cè)單例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) {
//從一級(jí)緩存中通過beanName拿取Bean
Object oldObject = this.singletonObjects.get(beanName);
//一級(jí)緩存中存在了,拋出IllegalStateException
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
}
//如果不存在,將singletonObject添加到一級(jí)緩存
addSingleton(beanName, singletonObject);
}
}
/**
* Add the given singleton object to the singleton cache of this factory.
* <p>To be called for eager registration of singletons.
* 把對(duì)象加入到單例緩存池中(所謂的一級(jí)緩存 并且考慮循環(huán)依賴和正常情況下,移除二三級(jí)緩存)
*
* @param beanName the name of the bean
* @param singletonObject the singleton object
*/
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
//將singletonObject添加到一級(jí)緩存中,同時(shí)移除二級(jí)、三級(jí)緩存、并標(biāo)記當(dāng)前Bean已注冊(cè)
this.singletonObjects.put(beanName, singletonObject);
//移除三級(jí)緩存
this.singletonFactories.remove(beanName);
//移除二級(jí)緩存
this.earlySingletonObjects.remove(beanName);
//標(biāo)記當(dāng)前Bean已被注冊(cè)
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.
* 該方法用于把早期對(duì)象包裝成一個(gè)ObjectFactory 暴露到三級(jí)緩存中 用于將解決循環(huán)依賴...
*
* @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) {
//單例緩存池中沒有包含當(dāng)前的bean
if (!this.singletonObjects.containsKey(beanName)) {
//加入到三級(jí)緩存中,,,,,暴露早期對(duì)象用于解決循環(huán)依賴
this.singletonFactories.put(beanName, singletonFactory);
//從二級(jí)緩存中移除
this.earlySingletonObjects.remove(beanName);
//標(biāo)記當(dāng)前Bean已經(jīng)被注冊(cè)過
this.registeredSingletons.add(beanName);
}
}
}
/**
* 該方法是一個(gè)空殼方法
*
* @param beanName the name of the bean to look for
* @return 緩存中的對(duì)象(有可能是一個(gè)單例完整對(duì)象, 也有可能是一個(gè)早期對(duì)象 ( 用于解決循環(huán)依賴))
*/
@Override
@Nullable
public Object getSingleton(String beanName) {
//在這里 系統(tǒng)一般是允許早期對(duì)象引用的 allowEarlyReference通過這個(gè)參數(shù)可以控制解決循環(huán)依賴
return getSingleton(beanName, true);
}
/**
* 在網(wǎng)上很多很多寫源碼的大佬或者是<spring源碼深度解析>一書上,也沒有說清楚為啥要使用三級(jí)緩存(二級(jí)緩存可不可以能夠
* 解決) 答案是:可以, 但是沒有很好的擴(kuò)展性為啥這么說.......
* 原因: 獲取三級(jí)緩存-----getEarlyBeanReference()經(jīng)過一系列的后置處理來給我們?cè)缙趯?duì)象進(jìn)行特殊化處理
* //從三級(jí)緩存中獲取包裝對(duì)象的時(shí)候 ,他會(huì)經(jīng)過一次后置處理器的處理對(duì)我們?cè)缙趯?duì)象的bean進(jìn)行
* 特殊化處理,但是spring的原生后置處理器沒有經(jīng)過處理,而是留給了我們程序員進(jìn)行擴(kuò)展
* singletonObject = singletonFactory.getObject();
* 把三級(jí)緩存移植到二級(jí)緩存中
* this.earlySingletonObjects.put(beanName, singletonObject);
* //刪除三級(jí)緩存中的之
* this.singletonFactories.remove(beanName);
*
* @param beanName bean的名稱
* @param allowEarlyReference 是否允許暴露早期對(duì)象 通過該參數(shù)可以控制是否能夠解決循環(huán)依賴的.
* @return 這里可能返回一個(gè)null(IOC容器加載單實(shí)例bean的時(shí)候,第一次進(jìn)來是返回null)
* 也有可能返回一個(gè)單例對(duì)象(IOC容器加載了單實(shí)例了,第二次來獲取當(dāng)前的Bean)
* 也可能返回一個(gè)早期對(duì)象(用于解決循環(huán)依賴問題)
*/
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
/**
* 第一步:我們嘗試去一級(jí)緩存(單例緩存池中去獲取對(duì)象,一般情況從該map中獲取的對(duì)象是直接可以使用的)
* IOC容器初始化加載單實(shí)例bean的時(shí)候第一次進(jìn)來的時(shí)候 該map中一般返回空
*/
Object singletonObject = this.singletonObjects.get(beanName);
//如果一級(jí)緩存為空,并且標(biāo)記正在創(chuàng)建
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
/**
* 嘗試去二級(jí)緩存中獲取對(duì)象(二級(jí)緩存中的對(duì)象是一個(gè)早期對(duì)象)
* 何為早期對(duì)象:就是bean剛剛調(diào)用了構(gòu)造方法,還來不及給bean的屬性進(jìn)行賦值的對(duì)象(純凈態(tài))
* 就是早期對(duì)象
*/
singletonObject = this.earlySingletonObjects.get(beanName);
/**
* 二級(jí)緩存中也沒有獲取到對(duì)象,allowEarlyReference為true(參數(shù)是有上一個(gè)方法傳遞進(jìn)來的true)
*/
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
/**
* 再次嘗試從一級(jí)緩存中去拿,如果還是沒拿到則嘗試去二級(jí)緩存中拿
*/
singletonObject = this.singletonObjects.get(beanName);
//一級(jí)緩存中沒拿到
if (singletonObject == null) {
//嘗試從二級(jí)緩存中去拿
singletonObject = this.earlySingletonObjects.get(beanName);
//二級(jí)緩存還是空
if (singletonObject == null) {
/**
* 直接從三級(jí)緩存中獲取 ObjectFactory對(duì)象 這個(gè)對(duì)接就是用來解決循環(huán)依賴的關(guān)鍵所在
* 在ioc后期的過程中,當(dāng)bean調(diào)用了構(gòu)造方法的時(shí)候,把早期對(duì)象包裹成一個(gè)ObjectFactory
* 暴露到三級(jí)緩存中
*/
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
//三級(jí)緩存中獲取的對(duì)象不為空
if (singletonFactory != null) {
/**
* 在這里通過暴露的ObjectFactory 包裝對(duì)象中,通過調(diào)用他的getObject()來獲取我們的早期對(duì)象
* 在這個(gè)環(huán)節(jié)中會(huì)調(diào)用到 getEarlyBeanReference()來進(jìn)行后置處理
*/
singletonObject = singletonFactory.getObject();
//把早期對(duì)象放置在二級(jí)緩存,
this.earlySingletonObjects.put(beanName, singletonObject);
//ObjectFactory 包裝對(duì)象從三級(jí)緩存中刪除掉
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
//返回這個(gè)Bean
return singletonObject;
}
/**
* Return the (raw) singleton object registered under the given name,
* creating and registering a new one if none registered yet.
* 獲取單例對(duì)象(該流程用于觸發(fā)構(gòu)建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) {
//嘗試從一級(jí)緩存池中獲取對(duì)象
Object singletonObject = this.singletonObjects.get(beanName);
//從一級(jí)緩存中沒拿到
if (singletonObject == null) {
//當(dāng)前是否是正在銷毀,是的話拋出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調(diào)試模式
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
/**
* 標(biāo)記當(dāng)前的bean馬上就要被創(chuàng)建了
* singletonsCurrentlyInCreation 在這里會(huì)把beanName加入進(jìn)來,若第二次循環(huán)依賴(構(gòu)造器注入會(huì)拋出異常)
*/
beforeSingletonCreation(beanName);
//標(biāo)記是否為新創(chuàng)建的單例Bean
boolean newSingleton = false;
//標(biāo)記是否記錄抑制異常
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
//如果為空,創(chuàng)建抑制異常集合
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 初始化 bean
// 這個(gè)過程其實(shí)是調(diào)用 createBean() 方法
singletonObject = singletonFactory.getObject();
//標(biāo)記這個(gè)Bean是新創(chuàng)建的
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.
//
//在此期間是否隱式創(chuàng)建了單例對(duì)象 -> 如果是,則繼續(xù)處理它,因?yàn)楫惓V冈摖顟B(tài)。
singletonObject = this.singletonObjects.get(beanName);
//一級(jí)緩存中沒有,拋出異常
if (singletonObject == null) {
throw ex;
}
} catch (BeanCreationException ex) {
//記錄抑制異常
if (recordSuppressedExceptions) {
//遍歷抑制異常集合,添加相關(guān)原因
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
//記錄抑制異常集合置空,復(fù)用
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
//后置處理
//主要做的事情就是把singletonsCurrentlyInCreation標(biāo)記正在創(chuàng)建的bean從集合中移除
afterSingletonCreation(beanName);
}
//是新建的單例Bean,添加到一級(jí)緩存中去
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}.
* 注冊(cè)在創(chuàng)建單例 bean 實(shí)例期間碰巧被抑制的異常,例如一個(gè)臨時(shí)的循環(huán)引用解析問題。
*
* @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 ,以便能夠在創(chuàng)建失敗時(shí)清除單例的急切注冊(cè)。
*
* @param beanName the name of the bean
* @see #getSingletonMutex()
*/
protected void removeSingleton(String beanName) {
//同步加鎖
synchronized (this.singletonObjects) {
//從一級(jí)緩存中移除
this.singletonObjects.remove(beanName);
//從三級(jí)緩存中移除
this.singletonFactories.remove(beanName);
//從二級(jí)緩存中移除
this.earlySingletonObjects.remove(beanName);
//從Bean注冊(cè)標(biāo)記集合中移除
this.registeredSingletons.remove(beanName);
}
}
/**
* 一級(jí)緩存中是否存在該Bean
*
* @param beanName the name of the bean to look for
* @return
*/
@Override
public boolean containsSingleton(String beanName) {
//判斷一級(jí)緩存中是否存在該Bean
return this.singletonObjects.containsKey(beanName);
}
/**
* 獲取已注冊(cè)的單例Bean名字的集合
*
* @return
*/
@Override
public String[] getSingletonNames() {
synchronized (this.singletonObjects) {
//獲取已注冊(cè)的單例Bean名字的集合
return StringUtils.toStringArray(this.registeredSingletons);
}
}
/**
* 獲取已注冊(cè)單例Bean實(shí)例的個(gè)數(shù)
*
* @return
*/
@Override
public int getSingletonCount() {
synchronized (this.singletonObjects) {
//獲取已注冊(cè)單例Bean實(shí)例的個(gè)數(shù)
return this.registeredSingletons.size();
}
}
/**
* 標(biāo)記當(dāng)前Bean正在創(chuàng)建,主要解決循環(huán)依賴
*
* @param beanName Bean名字
* @param inCreation 是否已標(biāo)記
*/
public void setCurrentlyInCreation(String beanName, boolean inCreation) {
//斷言Bean不為空
Assert.notNull(beanName, "Bean name must not be null");
//如果未標(biāo)記,將beanName加到inCreationCheckExclusions集合中,已標(biāo)記則移除
if (!inCreation) {
this.inCreationCheckExclusions.add(beanName);
} else {
this.inCreationCheckExclusions.remove(beanName);
}
}
/**
* 返回當(dāng)前Bean是否是正在創(chuàng)建
*
* @param beanName
* @return
*/
public boolean isCurrentlyInCreation(String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName));
}
/**
* 返回當(dāng)前Bean實(shí)際上是否在創(chuàng)建中
*
* @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 當(dāng)前是否正在創(chuàng)建中
*
* @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創(chuàng)建前回調(diào)方法,默認(rèn)實(shí)現(xiàn)將單例注冊(cè)為當(dāng)前正在創(chuàng)建中
*
* @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.
* 創(chuàng)建單例后回調(diào)。 默認(rèn)實(shí)現(xiàn)將單例標(biāo)記為不再創(chuàng)建。
*
* @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 添加到此注冊(cè)表中的一次性 bean 列表中。 一次性 bean 通常對(duì)應(yīng)于已注冊(cè)的單例,
* 與 bean 名稱匹配,但可能是不同的實(shí)例(例如,單例的 DisposableBean 適配器不自然實(shí)現(xiàn) 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.
* 注冊(cè)兩個(gè) bean 之間的包含關(guān)系,例如在內(nèi)部 bean 和包含它的外部 bean 之間。還根據(jù)銷毀順序?qū)?bean 注冊(cè)為依賴于所包含的 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 已經(jīng)檢測(cè)的依賴 bean
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
// 獲取原始 beanName
String canonicalName = canonicalName(beanName);
//獲取創(chuàng)建當(dāng)前bean 所依賴的bean的名稱集合
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
//不依賴任何前置Bean 直接返回
if (dependentBeans == null) {
return false;
}
// 存在,則證明存在已經(jīng)注冊(cè)的依賴
if (dependentBeans.contains(dependentBeanName)) {
return true;
}
// 遞歸檢測(cè)依賴
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是否注冊(cè)為依賴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);
}
//標(biāo)記為正在銷毀
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
}
String[] disposableBeanNames;
//獲取需要銷毀的Bean集合
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
//循環(huán)?;諉卫鼴ean
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
// 清空依賴和映射關(guān)系緩存
this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear();
// 清理Bean的一級(jí)二級(jí)三級(jí)緩存
clearSingletonCache();
}
/**
* Clear all cached singleton instances in this registry.
* 清除所有緩存的單例實(shí)例。
*
* @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.
//從緩存中移除當(dāng)前bean的相關(guān)信息,由于不知道在哪里發(fā)生異常,所以我們把跟當(dāng)前bean的所有緩存記錄都清除
removeSingleton(beanName);
// Destroy the corresponding DisposableBean instance.
//創(chuàng)建一個(gè)變量用于接受 實(shí)現(xiàn)了DisposableBean接口的對(duì)象變量
DisposableBean disposableBean;
synchronized (this.disposableBeans) {
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
//進(jìn)行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的依賴關(guān)系
*
* @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中保存的是當(dāng)前bean和依賴bean之間的映射
Set<String> dependencies;
synchronized (this.dependentBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
//把當(dāng)前創(chuàng)建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...
//真正的調(diào)用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的屬性關(guān)系的映射
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.
*/
/**
* 將單例互斥體暴露給子類和外部合作者。 如果子類執(zhí)行任何類型的擴(kuò)展單例創(chuàng)建階段,
* 它們應(yīng)該在給定的對(duì)象上同步。特別是子類不應(yīng)該在單例創(chuàng)建中使用它們自己的互斥鎖,
* 以避免在惰性初始化情況下潛在的死鎖。
*/
@Override
public final Object getSingletonMutex() {
return this.singletonObjects;
}
}它的方法大多為私有的,可以通過debug和反射,在這里我們通過反射來獲取私有的成員變量:
// DefaultSingletonBeanRegistry類管理所有的單例對(duì)象
//獲取所有的私有成員變量
Field singletonObjects =
DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
//允許可以訪問私有成員變量
singletonObjects.setAccessible(true);
//通過反射獲取
//獲取beanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//反射調(diào)用,獲取beanFactory的屬性
Map<String, Object> map = (Map<String, Object>) singletonObjects.get(beanFactory);
//過濾,獲取component相關(guān)的
map.entrySet().stream().filter(e -> e.getKey().startsWith("component"))
.forEach(e -> {
System.out.println(e.getKey() + "=" + e.getValue());
});總結(jié):
BeanFactory 能干點(diǎn)啥?
- 表面上只有 getBean
- 實(shí)際上控制反轉(zhuǎn)、基本的依賴注入、直至 Bean 的生命周期的各種功能,都由它的實(shí)現(xiàn)類提供
- 例子中通過反射查看了它的成員變量 singletonObjects,內(nèi)部包含了所有的單例 bean
到此這篇關(guān)于Spring BeanFactory工廠使用教程的文章就介紹到這了,更多相關(guān)Spring BeanFactory內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Jpa 實(shí)現(xiàn)自動(dòng)更新表中的創(chuàng)建日期和修改時(shí)間
這篇文章主要介紹了Jpa 實(shí)現(xiàn)自動(dòng)更新表中的創(chuàng)建日期和修改時(shí)間,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01
UrlDecoder和UrlEncoder使用詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了UrlDecoder和UrlEncoder使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
SpringBoot線上環(huán)境徹底關(guān)閉Swagger-UI的方式
這篇文章主要給大家介紹了SpringBoot線上環(huán)境徹底關(guān)閉Swagger-UI的方式,文中給出了詳細(xì)的代碼示例供大家參考,對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-12-12
解決Spring Boot 在localhost域奇怪的404問題(Mac book pro)
這篇文章主要介紹了解決Spring Boot 在localhost域奇怪的404問題(Mac book pro),需要的朋友可以參考下2017-09-09
利用ScriptEngineManager實(shí)現(xiàn)字符串公式靈活計(jì)算的方法
今天小編就為大家分享一篇利用ScriptEngineManager實(shí)現(xiàn)字符串公式靈活計(jì)算的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-07-07
idea tomcat亂碼問題的解決及相關(guān)設(shè)置的步驟
這篇文章主要介紹了idea tomcat亂碼問題的解決及相關(guān)設(shè)置的步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11

