<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
首先,我們想要知道一個介面有哪些功能,就必須要看這個介面的原始碼,在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 的生命週期的各種功能,都由它的實現類提供
來看一下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 能幹點啥?
到此這篇關於Spring BeanFactory工廠使用教學的文章就介紹到這了,更多相關Spring BeanFactory內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45