国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Spring源碼:Bean生命周期(終章)

這篇具有很好參考價(jià)值的文章主要介紹了Spring源碼:Bean生命周期(終章)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

前言

本系列前面講解了Spring的bean定義、bean實(shí)例化、bean初始化等生命周期。這些步驟使我們能夠了解bean從創(chuàng)建到準(zhǔn)備好使用所經(jīng)歷的過程。但是,除了這些步驟,bean的銷毀也是非常重要的一步。在本系列的最后,我們將深入探討bean的銷毀過程,包括在什么情況下會(huì)發(fā)生銷毀、銷毀的順序以及如何在bean銷毀之前執(zhí)行一些清理任務(wù)等。通過學(xué)習(xí)bean的銷毀過程,我們將更全面地了解Spring的bean生命周期。

在Spring中,有多種方式可以銷毀bean。其中一種方式是在應(yīng)用程序關(guān)閉時(shí)顯式地調(diào)用applicationContext.close()方法來關(guān)閉容器。這個(gè)方法將會(huì)銷毀所有還沒有被銷毀的bean。

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

applicationContext.close();

實(shí)現(xiàn)DisposableBean接口

實(shí)現(xiàn)DisposableBean接口是一種銷毀bean的簡單方式。當(dāng)bean容器關(guān)閉時(shí),Spring會(huì)調(diào)用DisposableBean的destroy()方法來銷毀bean。以下是一些示例代碼:

import org.springframework.beans.factory.DisposableBean;
@Component
public class MyBean implements DisposableBean {

    @Override
    public void destroy() throws Exception {
        // 在這里清理資源
    }
}

使用@PreDestroy注解

使用@PreDestroy注解是另一種簡單的方式來銷毀bean。當(dāng)bean容器關(guān)閉時(shí),Spring會(huì)調(diào)用使用@PreDestroy注解的方法來銷毀bean。以下是一些示例代碼:

import javax.annotation.PreDestroy;
@Component
public class MyBean {

    @PreDestroy
    public void cleanUp() throws Exception {
        // 在這里清理資源
    }
}

registerDisposableBeanIfNecessary

registerDisposableBeanIfNecessary()方法是一個(gè)非常重要的方法,它是在bean創(chuàng)建后進(jìn)行處理bean銷毀邏輯的前提。在Spring的AbstractBeanFactory類中,該方法會(huì)檢查當(dāng)前bean是否實(shí)現(xiàn)了DisposableBean接口或者@PreDestroy注解,如果是的話,就會(huì)將該bean添加到一個(gè)DisposableBeanAdapter對(duì)象中,該對(duì)象會(huì)在bean銷毀時(shí)被調(diào)用以執(zhí)行銷毀任務(wù)。這個(gè)過程是在bean銷毀之前執(zhí)行的,以確保正確關(guān)閉應(yīng)用程序。

    protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
        AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
        if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
            if (mbd.isSingleton()) {
                // Register a DisposableBean implementation that performs all destruction
                // work for the given bean: DestructionAwareBeanPostProcessors,
                // DisposableBean interface, custom destroy method.
                registerDisposableBean(beanName, new DisposableBeanAdapter(
                        bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
            }
            else {
                // A bean with a custom scope...
                Scope scope = this.scopes.get(mbd.getScope());
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
                }
                scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(
                        bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
            }
        }
    }

我大概講下這個(gè)方法requiresDestruction

    protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
        return (bean.getClass() != NullBean.class && (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) ||
                (hasDestructionAwareBeanPostProcessors() && DisposableBeanAdapter.hasApplicableProcessors(
                        bean, getBeanPostProcessorCache().destructionAware))));
    }
  1. DisposableBeanAdapter.hasDestroyMethod:校驗(yàn)是否實(shí)現(xiàn)了DisposableBean或者AutoCloseable接口,如果沒有的話,再查看是否bean定義的destroyMethodName屬性是(inferred),如果是的話,那么直接找這個(gè)類是否有close方法沒有的話再找shutdown方法
  2. DisposableBeanAdapter.hasApplicableProcessors:是否有@PreDestroy注解

DisposableBeanAdapter

DisposableBeanAdapter對(duì)象是一個(gè)適配器,用于在銷毀bean時(shí)執(zhí)行必要的處理。它會(huì)將DisposableBean接口或@PreDestroy注解的方法轉(zhuǎn)換為一個(gè)回調(diào)方法,以便在bean銷毀時(shí)執(zhí)行。這種適配器模式允許非標(biāo)準(zhǔn)的bean銷毀方法與Spring框架協(xié)同工作。

在將DisposableBeanAdapter對(duì)象添加到一個(gè)DisposableBeanRegistry對(duì)象中時(shí),Spring會(huì)將該對(duì)象添加到一個(gè)bean銷毀的注冊表中。當(dāng)需要銷毀所有bean時(shí),Spring就會(huì)從該注冊表中獲取所有需要銷毀的bean,并按照正確的順序執(zhí)行銷毀任務(wù)。這樣就可以確保應(yīng)用程序的正確關(guān)閉。

destroySingleton

當(dāng)Spring程序關(guān)閉時(shí),會(huì)調(diào)用destroyBeans方法,這里我們分析關(guān)鍵部分代碼:

    public void destroySingleton(String beanName) {
        // Remove a registered singleton of the given name, if any.
        // 先從單例池中移除掉
        removeSingleton(beanName);

        // Destroy the corresponding DisposableBean instance.
        DisposableBean disposableBean;
        synchronized (this.disposableBeans) {
            disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
        }
        destroyBean(beanName, disposableBean);
    }
  1. removeSingleton:先從單例池中移除掉
  2. this.disposableBeans.remove:這里返回的是我們之前調(diào)用registerDisposableBeanIfNecessary方法添加進(jìn)去的DisposableBeanAdapter適配器
  3. destroyBean:直接銷毀bean,這里注意一個(gè)小點(diǎn)就是如果當(dāng)前bean被其他bean依賴了,那么先移除銷毀其他Bean,然后就是調(diào)用適配器的destroy方法

總結(jié)

非常感謝您對(duì) Spring 生命周期系列文章的關(guān)注和支持,我們在過去一個(gè)月中深入了解了 Spring 框架中 Bean 的生成、初始化、后置處理和銷毀等過程,對(duì)于理解 Spring 框架的原理和機(jī)制非常有幫助。我們總結(jié)一下Spring到底做了那些事情將bean從生成到銷毀的全過程:

  1. 項(xiàng)目啟動(dòng)時(shí),ClassPathBeanDefinitionScanner掃描得到所有BeanDefinition,由于ACM技術(shù)所以此時(shí)beanclass屬性為String類型的bean的名稱
  2. 獲取合并后的BeanDefinition
  3. beanClass開始真正的被加載替換原有String類型的bean的名稱
  4. 調(diào)用實(shí)例化前處理方法applyBeanPostProcessorsBeforeInstantiation
  5. 通過構(gòu)造方法創(chuàng)建Bean實(shí)例
  6. 后置處理合并后的BeanDefinition,調(diào)用postProcessMergedBeanDefinition(尋找注入點(diǎn))
  7. 調(diào)用實(shí)例化后處理方法postProcessAfterInstantiation
  8. 開始進(jìn)行屬性注入:postProcessProperties
  9. 調(diào)用初始化前處理方法:applyBeanPostProcessorsBeforeInitialization
  10. 進(jìn)行初始化:invokeInitMethods,會(huì)調(diào)用指定init方法或者afterPropertiesSet方法
  11. 調(diào)用初始化后處理方法:applyBeanPostProcessorsAfterInitialization(AOP)
  12. 容器關(guān)閉時(shí),走bean的銷毀邏輯,即今天所講

這里面有很多邏輯流程我都在單獨(dú)的文章中有細(xì)講,比如FactoryBean、PropertyValues等等,由于是總結(jié)所以就不全寫出來了,也希望大家可以好好理解Spring源碼,下一步,我們將會(huì)著重講解 Bean 的屬性依賴注入。文章來源地址http://www.zghlxwxcb.cn/news/detail-456276.html

到了這里,關(guān)于Spring源碼:Bean生命周期(終章)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Spring源碼:Bean的生命周期(二)

    讓我們繼續(xù)講解Spring的Bean實(shí)例化過程。在上一節(jié)中,我們已經(jīng)講解了Spring是如何將Bean定義加入到IoC容器中,并使用合并的Bean定義來包裝原始的Bean定義。接下來,我們將繼續(xù)講解Spring的 getBean() 方法,特別是針對(duì) FactoryBean 的解析。 在 getBean() 方法中,Spring還支持對(duì) FactoryBea

    2024年02月02日
    瀏覽(33)
  • Spring源碼:bean的生命周期(一)

    Spring源碼:bean的生命周期(一)

    本節(jié)將正式介紹Spring源碼細(xì)節(jié),將講解Bean生命周期。請注意,雖然我們不希望過于繁瑣地理解Spring源碼,但也不要認(rèn)為Spring源碼很簡單。在本節(jié)中,我們將主要講解Spring 5.3.10版本的源代碼。如果您看到的代碼與我講解的不同,也沒有關(guān)系,因?yàn)槠渲械脑砗蜆I(yè)務(wù)邏輯基本相

    2024年02月02日
    瀏覽(23)
  • 【Spring源碼】講講Bean的生命周期

    【Spring源碼】講講Bean的生命周期

    面試官:“看過Spring源碼吧,簡單說說Spring中Bean的生命周期” 大神仙:“基本生命周期會(huì)經(jīng)歷實(shí)例化 - 屬性賦值 - 初始化 - 銷毀”。 面試官:“......” 如果是普通Bean的生命周期,那么上述的回答是真正確的。確實(shí)會(huì)經(jīng)歷“實(shí)例化 - 屬性賦值 - 初始化 - 銷毀”四個(gè)階段。但

    2023年04月09日
    瀏覽(20)
  • 【Spring】Spring之Bean生命周期源碼解析

    什么是bean的生命周期 是指bean在spring中是如何生成,如何銷毀的; spring創(chuàng)建對(duì)象的過程,就是IOC(控制反轉(zhuǎn))的過程; JFR Java Flight Record,java飛行記錄,類似于飛機(jī)的黑匣子,是JVM內(nèi)置的基于事件的JDK監(jiān)控記錄框架,主要用于問題定位和持續(xù)監(jiān)控; 入口代碼: Spring啟動(dòng)的時(shí)

    2024年02月15日
    瀏覽(23)
  • 【框架源碼】Spring源碼解析之Bean生命周期流程

    【框架源碼】Spring源碼解析之Bean生命周期流程

    觀看本文前,我們先思考一個(gè)問題,什么是Spring的bean的生命周期?這也是我們在面試的時(shí)候,面試官常問的一個(gè)問題。 在沒有Spring之前,我們創(chuàng)建對(duì)象的時(shí)候,采用new的方式,當(dāng)對(duì)象不在被使用的時(shí)候,由Java的垃圾回收機(jī)制回收。 而 Spring 中的對(duì)象是 bean,bean 和普通的 J

    2024年02月09日
    瀏覽(21)
  • 【深入Spring源碼解析:解密Bean的生命周期】

    Spring是Java企業(yè)級(jí)應(yīng)用開發(fā)領(lǐng)域的一顆明星,它提供了很多方便開發(fā)人員的工具和思想。在分布式系統(tǒng)中,Spring的分布式遠(yuǎn)程協(xié)作方案,比如REST、Web服務(wù)以及消息傳遞等,也是不可或缺的。 你知道嗎?在我們使用Spring時(shí),容器中存放的所有對(duì)象,在Spring啟動(dòng)的時(shí)候就完成了實(shí)

    2024年02月05日
    瀏覽(28)
  • Spring系列4 -- Bean的作用域和生命周期

    Spring系列4 -- Bean的作用域和生命周期

    目錄 1. 案例 2. 作用域定義 2.1 Bean的6種作用域 2.2 設(shè)置作用域 3. Sring的執(zhí)行流程 4. Bean的生命周期 思考: 為什么不是先進(jìn)行初始化然后再進(jìn)行設(shè)置屬性呢? ????????假設(shè)現(xiàn)在有?個(gè)公共的 Bean,提供給 A ?戶和 B ?戶使?,然?在使?的途中 A ?戶卻“悄悄”地修改了公共

    2024年02月15日
    瀏覽(24)
  • Spring窺探系列之Bean生命周期(100%GPT生成版)

    Spring Bean 的生命周期可以分為以下階段: 實(shí)例化:Spring 容器根據(jù) Bean 的定義創(chuàng)建一個(gè) Bean 的實(shí)例。這個(gè)階段主要涉及 Bean 的實(shí)例化和依賴注入。 相關(guān)類:InstantiationAwareBeanPostProcessor、BeanFactoryPostProcessor、BeanPostProcessor、BeanWrapper、DefaultListableBeanFactory 等。 屬性賦值:所有的

    2024年02月15日
    瀏覽(23)
  • 【Spring專題】Spring之Bean的生命周期源碼解析——上(掃描生成BeanDefinition)

    【Spring專題】Spring之Bean的生命周期源碼解析——上(掃描生成BeanDefinition)

    由于Spring源碼分析是一個(gè)前后聯(lián)系比較強(qiáng)的過程,而且這邊分析,也是按照代碼順序講解的,所以不了解前置知識(shí)的情況下,大概率沒辦法看懂當(dāng)前的內(nèi)容。所以,特別推薦看看我前面的文章(自上而下次序): Spring底層核心原理解析——引導(dǎo)篇【學(xué)習(xí)難度: ★★☆☆☆ 】

    2024年02月13日
    瀏覽(22)
  • 【Spring專題】Spring之Bean的生命周期源碼解析——階段一(掃描生成BeanDefinition)

    【Spring專題】Spring之Bean的生命周期源碼解析——階段一(掃描生成BeanDefinition)

    由于Spring源碼分析是一個(gè)前后聯(lián)系比較強(qiáng)的過程,而且這邊分析,也是按照代碼順序講解的,所以不了解前置知識(shí)的情況下,大概率沒辦法看懂當(dāng)前的內(nèi)容。所以,特別推薦看看我前面的文章(自上而下次序): Spring底層核心原理解析——引導(dǎo)篇【學(xué)習(xí)難度: ★★☆☆☆ 】

    2024年02月13日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包