欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot關(guān)閉過程中銷毀DisposableBean解讀

 更新時間:2023年12月05日 11:25:54   作者:流煙默  
這篇文章主要介紹了SpringBoot關(guān)閉過程中銷毀DisposableBean解讀,一個bean的生命周期,指的是 bean 從創(chuàng)建,初始化,一系列使用,銷毀的過程,今天來講講 bean 的初始化和銷毀的方法,需要的朋友可以參考下

DisposableBean的destroy過程

DefaultSingletonBeanRegistry的destroySingleton方法。

public void destroySingleton(String beanName) {
	// Remove a registered singleton of the given name, if any.
	// 從緩存中移除當(dāng)前beanName
	removeSingleton(beanName);
	// Destroy the corresponding DisposableBean instance.
	// 從disposableBeans集合中移除當(dāng)前 beanName
	DisposableBean disposableBean;
	synchronized (this.disposableBeans) {
		disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
	}
	// 這是核心方法
	destroyBean(beanName, disposableBean);
}

disposableBeans里面存放的是beanName以及對應(yīng)的DisposableBeanAdapter實例。其他方法我們過一下即可,這里我們著重分析destroyBean(beanName, disposableBean);。

核心方法DefaultSingletonBeanRegistry的destroyBean

// DefaultSingletonBeanRegistry
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
	// Trigger destruction of dependent beans first...
	Set<String> dependencies;
	//dependentBeanMap存放的是哪些bean依賴于key
	synchronized (this.dependentBeanMap) {
		// Within full synchronization in order to guarantee a disconnected Set
		dependencies = this.dependentBeanMap.remove(beanName);
	}
	// 首先觸發(fā)那些依賴于當(dāng)前beanName的bean的銷毀流程
	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...
	// bean銷毀的過程入口,觸發(fā)DisposableBeanAdapter的destroy方法
	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...
	// 獲取當(dāng)前beanName對應(yīng)的containedBeans,如果有,則遍歷觸發(fā)銷毀流程
	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的value,移除掉當(dāng)前beanName。
	//之后如果value為空,其從dependentBeanMap移除掉當(dāng)前entry
	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中移除當(dāng)前beanName對應(yīng)的entry
	this.dependenciesForBeanMap.remove(beanName);
}

方法邏輯梳理如下:

  • 首先觸發(fā)那些依賴于當(dāng)前beanName的bean的銷毀流程
  • bean.destroy();觸發(fā)DisposableBeanAdapter的destroy方法
  • 獲取當(dāng)前實例維護的DestructionAwareBeanPostProcessor 觸發(fā)其postProcessBeforeDestruction方法,如果有@PreDestroy注解的方法,這時會被觸發(fā)。
  • 根據(jù)invokeDisposableBean判斷是否觸發(fā)destroy方法
  • 嘗試觸發(fā)其自定義destroy method
  • 獲取當(dāng)前beanName對應(yīng)的containedBeans,如果有,則遍歷觸發(fā)銷毀流程
  • 遍歷dependentBeanMap的value,移除掉當(dāng)前beanName。之后如果value為空,其從dependentBeanMap移除掉當(dāng)前entry
  • 從 dependenciesForBeanMap中移除當(dāng)前beanName對應(yīng)的entry

DisposableBeanAdapter

上面提到了bean.destroy();觸發(fā)DisposableBeanAdapter的destroy方法,方法如下所示:

@Override
public void destroy() {
//獲取當(dāng)前實例維護的DestructionAwareBeanPostProcessor 觸發(fā)其postProcessBeforeDestruction方法
	if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
		for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
			processor.postProcessBeforeDestruction(this.bean, this.beanName);
		}
	}
// 是否觸發(fā)destroy方法
	if (this.invokeDisposableBean) {
		if (logger.isTraceEnabled()) {
			logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
		}
		try {
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
					((DisposableBean) this.bean).destroy();
					return null;
				}, this.acc);
			}
			else {
				((DisposableBean) this.bean).destroy();
			}
		}
		catch (Throwable ex) {
			String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
			if (logger.isDebugEnabled()) {
				logger.warn(msg, ex);
			}
			else {
				logger.warn(msg + ": " + ex);
			}
		}
	}
// 如果destroyMethod 不為null,則觸發(fā)自定義銷毀方法
	if (this.destroyMethod != null) {
		invokeCustomDestroyMethod(this.destroyMethod);
	}
	else if (this.destroyMethodName != null) {
	// 如果destroyMethodName 不為null,則獲取并觸發(fā)自定義銷毀方法
		Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
		if (methodToInvoke != null) {
			invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
		}
	}
}

方法流程

獲取當(dāng)前實例維護的DestructionAwareBeanPostProcessor 觸發(fā)其postProcessBeforeDestruction方法,如果有@PreDestroy注解的方法,這時會被觸發(fā)。

根據(jù)invokeDisposableBean判斷是否觸發(fā)destroy方法

嘗試觸發(fā)其自定義destroy method

到此這篇關(guān)于SpringBoot關(guān)閉過程中銷毀DisposableBean解讀的文章就介紹到這了,更多相關(guān)SpringBoot銷毀DisposableBean內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Springboot配置Swagger的實現(xiàn)示例

    Springboot配置Swagger的實現(xiàn)示例

    Swagger 是一種提高 API 開發(fā)和維護效率的工具,它使開發(fā)者能夠更輕松地構(gòu)建、測試和文檔化 API,本文主要介紹了Springboot配置Swagger的實現(xiàn)示例,感興趣的可以了解一下
    2023-10-10
  • Java過濾器Filter的基本使用教程

    Java過濾器Filter的基本使用教程

    過濾器通常對一些web資源進(jìn)行攔截,做完一些處理器再交給下一個過濾器處理,直到所有的過濾器處理器,再調(diào)用servlet實例的service方法進(jìn)行處理。本文將通過示例為大家講解Java中過濾器Filter的用法與實現(xiàn),需要的可以參考一下
    2023-02-02
  • java 文件和byte互轉(zhuǎn)的實例

    java 文件和byte互轉(zhuǎn)的實例

    下面小編就為大家分享一篇java 文件和byte互轉(zhuǎn)的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-11-11
  • IDEA報錯:Unable to save settings Failed to save settings

    IDEA報錯:Unable to save settings Failed to save settings

    這篇文章主要介紹了IDEA報錯:Unable to save settings Failed to save settings的相關(guān)知識,本文給大家分享問題原因及解決方案,需要的朋友可以參考下
    2020-09-09
  • Java BufferedOutputStream類的常用方法講解

    Java BufferedOutputStream類的常用方法講解

    這篇文章主要介紹了Java BufferedOutputStream類的常用方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • SpringBoot?Schedule調(diào)度任務(wù)的動態(tài)管理

    SpringBoot?Schedule調(diào)度任務(wù)的動態(tài)管理

    Scheduled定時任務(wù)是Spring?boot自身提供的功能,所以不需要引入Maven依賴包,下面這篇文章主要給大家介紹了關(guān)于SpringBoot通過@Scheduled實現(xiàn)定時任務(wù)以及問題解決的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • Spring Boot整合SSE實時通信的問題小結(jié)

    Spring Boot整合SSE實時通信的問題小結(jié)

    本文介紹了服務(wù)器發(fā)送事件(Server-Sent Events,SSE)技術(shù),其主要特點包括單向數(shù)據(jù)流、自動重連、自定義事件類型等,SSE適用于實時更新場景,如新聞推送、評論系統(tǒng)等,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • 利用java實現(xiàn)一個客戶信息管理系統(tǒng)

    利用java實現(xiàn)一個客戶信息管理系統(tǒng)

    這篇文章主要給大家介紹了關(guān)于利用java實現(xiàn)一個客戶信息管理系統(tǒng)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Java.lang.NullPointerException的錯誤解決

    Java.lang.NullPointerException的錯誤解決

    Java中NullPointerException是一種常見的運行時異常,通常發(fā)生在嘗試調(diào)用null對象的方法或訪問其屬性時,具有一定的參考價值,感興趣的可以了解一下
    2024-09-09
  • Java中的synchronized關(guān)鍵字

    Java中的synchronized關(guān)鍵字

    這篇文章主要介紹了Java中的synchronized關(guān)鍵字,synchronized可以保證方法或代碼塊在運行時,同一時刻只有一個線程可以進(jìn)入到臨界區(qū)(互斥性),同時它還保證了共享變量的內(nèi)存可見性,下面我們就來看看你文章對synchronized鎖的介紹,需要的朋友也可以參考一下
    2021-12-12

最新評論