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

Spring Bean三級(jí)緩存機(jī)制的技術(shù)指南

 更新時(shí)間:2025年04月10日 10:13:07   作者:拾荒的小海螺  
在 Spring 框架中,Bean 的創(chuàng)建和管理是容器的核心功能之一,了提高性能,Spring 采用了多級(jí)緩存機(jī)制來(lái)減少不必要的對(duì)象創(chuàng)建和配置,本文將詳細(xì)介紹 Spring 中 Bean 三級(jí)緩存的實(shí)現(xiàn)原理,并通過(guò)代碼示例幫助你理解這個(gè)機(jī)制的工作方式,需要的朋友可以參考下

1、簡(jiǎn)述

在 Spring 框架中,Bean 的創(chuàng)建和管理是容器的核心功能之一。為了提高性能,Spring 采用了多級(jí)緩存機(jī)制來(lái)減少不必要的對(duì)象創(chuàng)建和配置。特別是在 Spring 的單例 Bean 的管理中,三級(jí)緩存機(jī)制是一個(gè)非常重要的優(yōu)化手段。它的目的是減少對(duì) Bean 的多次初始化,確保線程安全,并提高應(yīng)用程序的啟動(dòng)性能。

本文將詳細(xì)介紹 Spring 中 Bean 三級(jí)緩存的實(shí)現(xiàn)原理,并通過(guò)代碼示例幫助你理解這個(gè)機(jī)制的工作方式。

2、什么是 Spring Bean 三級(jí)緩存?

Spring 的三級(jí)緩存是 Spring 容器在創(chuàng)建和管理單例 Bean 時(shí)使用的一種緩存機(jī)制。它主要用于解決多線程環(huán)境下對(duì)同一個(gè) Bean 實(shí)例化的并發(fā)問(wèn)題。Spring 三級(jí)緩存分為以下三類:

  • 一級(jí)緩存:存儲(chǔ)已經(jīng)完全初始化的單例 Bean。
  • 二級(jí)緩存:存儲(chǔ)已經(jīng)實(shí)例化但尚未完全初始化的 Bean 實(shí)例。
  • 三級(jí)緩存:存儲(chǔ)待初始化的 Bean 代理對(duì)象,通常用于解決 Bean 循環(huán)依賴。

通過(guò)三級(jí)緩存,Spring 能夠在不同階段緩存 Bean 實(shí)例,確保 Bean 在多線程環(huán)境中的安全性,并避免重復(fù)的初始化工作。

3、Spring 三級(jí)緩存的實(shí)現(xiàn)機(jī)制

Spring 通過(guò) DefaultSingletonBeanRegistry 類實(shí)現(xiàn)了 Bean 的三級(jí)緩存。下面是三級(jí)緩存機(jī)制的具體實(shí)現(xiàn)流程。

  • 一級(jí)緩存(singletonObjects):存放已完全初始化的單例 Bean。在 Bean 初始化完成后,會(huì)被加入一級(jí)緩存中,供后續(xù)的調(diào)用使用。
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
  • 二級(jí)緩存earlySingletonObjects):存放已經(jīng)實(shí)例化但未完全初始化的 Bean。當(dāng) Spring 處理 Bean 的依賴注入和初始化時(shí),這些 Bean 實(shí)例會(huì)放入二級(jí)緩存。
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
  • 三級(jí)緩存singletonFactories):存放待初始化 Bean 的代理工廠。當(dāng)遇到循環(huán)依賴時(shí),Spring 會(huì)創(chuàng)建一個(gè)代理對(duì)象(通常是 CGLIB 或 JDK 動(dòng)態(tài)代理)并放入三級(jí)緩存中,防止在 Bean 初始化過(guò)程中多次創(chuàng)建相同的對(duì)象。
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

4、Spring 三級(jí)緩存的工作流程

  • 實(shí)例化 Bean
    當(dāng) Spring 容器啟動(dòng)時(shí),它會(huì)根據(jù) Bean 的配置來(lái)決定是否需要實(shí)例化該 Bean。實(shí)例化的過(guò)程是通過(guò) createBean 方法來(lái)完成的。

  • 依賴注入與初始化
    在實(shí)例化 Bean 后,Spring 會(huì)將 Bean 的依賴項(xiàng)注入到 Bean 中(即調(diào)用 Bean 的 setter 方法或構(gòu)造器注入)。隨后,Spring 會(huì)執(zhí)行 Bean 的初始化方法。

  • 循環(huán)依賴的解決
    如果 Spring 在初始化 Bean 時(shí)發(fā)現(xiàn)該 Bean 存在循環(huán)依賴問(wèn)題(例如 A 依賴 B,B 又依賴 A),Spring 會(huì)通過(guò)三級(jí)緩存來(lái)避免重復(fù)的創(chuàng)建過(guò)程。具體而言,Spring 會(huì)創(chuàng)建一個(gè)代理 Bean,并將其放入三級(jí)緩存中,確保在循環(huán)依賴的情況下仍能順利完成 Bean 的創(chuàng)建和注入。

  • Bean 完成初始化
    在 Bean 完成初始化后,它會(huì)被加入到一級(jí)緩存中,表示該 Bean 已經(jīng)是一個(gè)完全初始化的對(duì)象。

以下是 Spring 中 Bean 三級(jí)緩存的實(shí)現(xiàn)代碼示例,演示了 Spring 如何使用三級(jí)緩存來(lái)解決循環(huán)依賴問(wèn)題。

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
import org.springframework.beans.factory.support.SingletonBeanRegistry;

public class CustomSingletonBeanRegistry extends DefaultSingletonBeanRegistry {

    @Override
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // 獲取 Bean 時(shí),先嘗試從一級(jí)緩存中獲取
        Object singleton = super.getSingleton(beanName);
        if (singleton != null) {
            return singleton;
        }

        // 若一級(jí)緩存中沒(méi)有,則檢查是否需要從二級(jí)緩存中獲取
        if (allowEarlyReference) {
            singleton = earlySingletonObjects.get(beanName);
            if (singleton != null) {
                return singleton;
            }
        }

        // 若二級(jí)緩存中也沒(méi)有,則從三級(jí)緩存(即singletonFactories)中獲取
        singleton = singletonFactories.get(beanName);
        if (singleton != null) {
            return singleton;
        }

        // 如果三級(jí)緩存中也沒(méi)有,就執(zhí)行標(biāo)準(zhǔn)的實(shí)例化過(guò)程
        return createBean(beanName);
    }
}

public class BeanLifecycleExample {

    public static void main(String[] args) {
        SingletonBeanRegistry beanRegistry = new CustomSingletonBeanRegistry();
        
        // 模擬一個(gè)循環(huán)依賴的情況:A依賴B,B依賴A
        beanRegistry.registerSingleton("A", new A(beanRegistry));
        beanRegistry.registerSingleton("B", new B(beanRegistry));

        A aBean = (A) beanRegistry.getSingleton("A", true);
        System.out.println(aBean);
    }
}

class A {
    private final SingletonBeanRegistry registry;
    
    public A(SingletonBeanRegistry registry) {
        this.registry = registry;
        System.out.println("A bean instantiated");
    }

    public void setB(B b) {
        System.out.println("B injected into A");
    }
}

class B {
    private final SingletonBeanRegistry registry;
    
    public B(SingletonBeanRegistry registry) {
        this.registry = registry;
        System.out.println("B bean instantiated");
    }

    public void setA(A a) {
        System.out.println("A injected into B");
    }
}

在這個(gè)例子中,我們創(chuàng)建了 A 和 B 兩個(gè)類,它們互相依賴。通過(guò)自定義 SingletonBeanRegistry 類,我們可以模擬 Spring 通過(guò)三級(jí)緩存來(lái)解決循環(huán)依賴問(wèn)題。

5、三級(jí)緩存的作用與優(yōu)勢(shì)

  • 減少實(shí)例化開銷
    Spring 通過(guò)緩存已實(shí)例化的 Bean 和未完全初始化的 Bean,避免了每次需要獲取 Bean 時(shí)都重新實(shí)例化。這樣可以減少大量的性能開銷。

  • 解決循環(huán)依賴
    通過(guò)三級(jí)緩存,Spring 能夠在遇到循環(huán)依賴時(shí),不會(huì)無(wú)限遞歸地創(chuàng)建 Bean,從而避免了死循環(huán)。三級(jí)緩存存儲(chǔ)了 Bean 的代理對(duì)象,可以在循環(huán)依賴中起到替代作用。

  • 提高性能
    通過(guò)緩存機(jī)制,Spring 能夠提高 Bean 的創(chuàng)建效率,尤其是在高并發(fā)環(huán)境下,減少了不必要的對(duì)象創(chuàng)建和初始化,提高了應(yīng)用程序的啟動(dòng)速度。

6、總結(jié)

Spring 的 Bean 三級(jí)緩存是一個(gè)關(guān)鍵的優(yōu)化機(jī)制,旨在解決 Bean 實(shí)例化過(guò)程中的循環(huán)依賴問(wèn)題,提升性能。它通過(guò)將單例 Bean 分為三級(jí)緩存(一級(jí)緩存、二級(jí)緩存、三級(jí)緩存)來(lái)減少多線程環(huán)境下的實(shí)例化開銷,并確保線程安全。理解并掌握 Spring 三級(jí)緩存的實(shí)現(xiàn)原理,能夠幫助我們更高效地使用 Spring 框架,特別是在處理復(fù)雜的依賴關(guān)系時(shí)。

以上就是Spring Bean三級(jí)緩存機(jī)制的技術(shù)指南的詳細(xì)內(nèi)容,更多關(guān)于Spring Bean三級(jí)緩存機(jī)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 解決spring mvc 多數(shù)據(jù)源切換,不支持事務(wù)控制的問(wèn)題

    解決spring mvc 多數(shù)據(jù)源切換,不支持事務(wù)控制的問(wèn)題

    下面小編就為大家?guī)?lái)一篇解決spring mvc 多數(shù)據(jù)源切換,不支持事務(wù)控制的問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • 簡(jiǎn)單了解Java刪除字符replaceFirst原理及實(shí)例

    簡(jiǎn)單了解Java刪除字符replaceFirst原理及實(shí)例

    這篇文章主要介紹了簡(jiǎn)單了解Java刪除字符replaceFirst原理及實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • SpringCloud邁向云原生的步驟

    SpringCloud邁向云原生的步驟

    這篇文章主要介紹了SpringCloud怎么邁向云原生,通過(guò)本文我們來(lái)梳理一下Spring?Cloud的前世今生,以及未來(lái)云原生發(fā)展的趨勢(shì),可以給這些RPC框架的演進(jìn)帶來(lái)一些啟發(fā),感興趣的朋友跟隨小編一起看看吧
    2022-10-10
  • RocketMQ消息存儲(chǔ)文件的加載與恢復(fù)機(jī)制源碼分析

    RocketMQ消息存儲(chǔ)文件的加載與恢復(fù)機(jī)制源碼分析

    這篇文章主要介紹了RocketMQ源碼分析之消息存儲(chǔ)文件的加載與恢復(fù)機(jī)制詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • 原理分析SonarQube中IdentityProvider賬戶互斥現(xiàn)象

    原理分析SonarQube中IdentityProvider賬戶互斥現(xiàn)象

    這篇文章主要為大家介紹分析SonarQube中IdentityProvider賬戶互斥現(xiàn)象原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • Java如何正確的使用wait-notify方法你知道嗎

    Java如何正確的使用wait-notify方法你知道嗎

    這篇文章主要為大家詳細(xì)介紹了Java如何正確的使用wait-notify方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • spring mvc實(shí)現(xiàn)文件上傳并攜帶其他參數(shù)的示例

    spring mvc實(shí)現(xiàn)文件上傳并攜帶其他參數(shù)的示例

    本篇文章主要介紹了spring mvc實(shí)現(xiàn)文件上傳并攜帶其他參數(shù)的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-02-02
  • Springboot中@Transactional注解與異常處理機(jī)制方式

    Springboot中@Transactional注解與異常處理機(jī)制方式

    這篇文章主要介紹了Springboot中@Transactional注解與異常處理機(jī)制方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 使用Java添加、刪除與預(yù)覽Excel分頁(yè)符全攻略

    使用Java添加、刪除與預(yù)覽Excel分頁(yè)符全攻略

    在日常辦公或者數(shù)據(jù)處理場(chǎng)景中,我們經(jīng)常需要對(duì)Excel表格進(jìn)行分頁(yè)操作,通過(guò)?Java?操作?Excel,我們可以自動(dòng)化設(shè)置、刪除以及預(yù)覽分頁(yè)符,大大提升效率,本文將結(jié)合實(shí)際示例,深入講解如何在Java中使用Spire.XLS庫(kù)來(lái)管理Excel表格的分頁(yè)符,需要的朋友可以參考下
    2026-04-04
  • springboot整合druid及多數(shù)據(jù)源配置的demo

    springboot整合druid及多數(shù)據(jù)源配置的demo

    這篇文章主要介紹了springboot整合druid及多數(shù)據(jù)源配置的demo,本篇主要分兩部分 ①springboot整合druid的代碼配置,以及druid的監(jiān)控頁(yè)面演示;②對(duì)實(shí)際場(chǎng)景中多數(shù)據(jù)源的配置使用進(jìn)行講解,需要的朋友可以參考下
    2024-01-01

最新評(píng)論

丹江口市| 墨竹工卡县| 屯昌县| 南充市| 达日县| 扎赉特旗| 东丰县| 达拉特旗| 卢龙县| 东海县| 白沙| 莒南县| 新泰市| 临西县| 东台市| 吴忠市| 冷水江市| 龙陵县| 峨眉山市| 山阳县| 教育| 开远市| 江陵县| 荣成市| 神池县| 琼海市| 永新县| 兰溪市| 晋城| 腾冲县| 饶河县| 琼中| 揭西县| 宁安市| 桐乡市| 南雄市| 汝南县| 翁牛特旗| 怀安县| 牟定县| 龙陵县|