最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot關閉過程中銷毀DisposableBean解讀

 更新時間:2023年12月05日 11:25:54   作者:流煙默  
這篇文章主要介紹了SpringBoot關閉過程中銷毀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.
	// 從緩存中移除當前beanName
	removeSingleton(beanName);
	// Destroy the corresponding DisposableBean instance.
	// 從disposableBeans集合中移除當前 beanName
	DisposableBean disposableBean;
	synchronized (this.disposableBeans) {
		disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
	}
	// 這是核心方法
	destroyBean(beanName, disposableBean);
}

disposableBeans里面存放的是beanName以及對應的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ā)那些依賴于當前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...
	// 獲取當前beanName對應的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,移除掉當前beanName。
	//之后如果value為空,其從dependentBeanMap移除掉當前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中移除當前beanName對應的entry
	this.dependenciesForBeanMap.remove(beanName);
}

方法邏輯梳理如下:

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

DisposableBeanAdapter

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

@Override
public void destroy() {
//獲取當前實例維護的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));
		}
	}
}

方法流程

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

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

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

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

相關文章

  • 剖析Java中的事件處理與異常處理機制

    剖析Java中的事件處理與異常處理機制

    這篇文章主要介紹了Java中的事件處理與異常處理機制,講解Java是如何對事件或者異常作出響應以及定義異常的一些方法,需要的朋友可以參考下
    2016-01-01
  • Java實現(xiàn)字節(jié)字符轉bcd編碼

    Java實現(xiàn)字節(jié)字符轉bcd編碼

    BCD是一種將十進制數(shù)字編碼為二進制的表示方式,常用于數(shù)字顯示和存儲,本文將介紹如何在Java中實現(xiàn)字節(jié)字符轉BCD碼的過程,需要的小伙伴可以了解下
    2025-09-09
  • 解決MyBatis返回結果類型為Boolean的問題

    解決MyBatis返回結果類型為Boolean的問題

    這篇文章主要介紹了解決MyBatis返回結果類型為Boolean的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Java Servlet線程中AsyncContext異步處理Http請求

    Java Servlet線程中AsyncContext異步處理Http請求

    這篇文章主要介紹了Java Servlet線程中AsyncContext異步處理Http請求及在業(yè)務中應用,AsyncContext是Servlet 3.0使Servlet 線程不再需要一直阻塞,直到業(yè)務處理完畢才能再輸出響應,最后才結束該Servlet線程
    2023-03-03
  • 這一次搞懂Spring事務是如何傳播的

    這一次搞懂Spring事務是如何傳播的

    這篇文章主要介紹了這一次搞懂Spring事務是如何傳播的,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • Java跳出多重嵌套循環(huán)過程解析

    Java跳出多重嵌套循環(huán)過程解析

    這篇文章主要介紹了Java跳出多重嵌套循環(huán)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • MyBatis?和?MyBatis-Plus從語法詳解和優(yōu)劣對比

    MyBatis?和?MyBatis-Plus從語法詳解和優(yōu)劣對比

    MyBatis和MyBatis-Plus是Java生態(tài)中常用的持久層框架,其中?MyBatis-Plus是在?MyBatis?基礎上的增強工具,下面從語法詳解和優(yōu)劣對比兩部分展開說明,感興趣的朋友一起看看吧
    2025-07-07
  • Java日常練習題,每天進步一點點(29)

    Java日常練習題,每天進步一點點(29)

    下面小編就為大家?guī)硪黄狫ava基礎的幾道練習題(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-07-07
  • SpringCloud Alibaba使用Seata處理分布式事務的技巧

    SpringCloud Alibaba使用Seata處理分布式事務的技巧

    在傳統(tǒng)的單體項目中,我們使用@Transactional注解就能實現(xiàn)基本的ACID事務了,隨著微服務架構的引入,需要對數(shù)據(jù)庫進行分庫分表,每個服務擁有自己的數(shù)據(jù)庫,這樣傳統(tǒng)的事務就不起作用了,那么我們如何保證多個服務中數(shù)據(jù)的一致性呢?跟隨小編一起通過本文了解下吧
    2021-06-06
  • 淺析Java中的內存泄漏

    淺析Java中的內存泄漏

    這篇文章主要介紹了Java中的內存泄漏,包括其基本概念和基本的預防措施,需要的朋友可以參考下
    2015-07-07

最新評論

延庆县| 麟游县| 黄梅县| 黄陵县| 德州市| 灵璧县| 宝应县| 安平县| 绥江县| 大兴区| 曲松县| 黑龙江省| 阿拉尔市| 香港| 乌海市| 无为县| 沈丘县| 原平市| 综艺| 呼玛县| 平原县| 霞浦县| 林西县| 永昌县| 阿合奇县| 新源县| 瓮安县| 桃源县| 喀喇| 遂溪县| 磴口县| 康马县| 大名县| 蓬安县| 丹东市| 高邮市| 武城县| 扎鲁特旗| 涟源市| 台南市| 左权县|