<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Spring Refresh on 小蜜蜂</title>
        <link>https://xumf.net/tags/spring-refresh/</link>
        <description>Recent content in Spring Refresh on 小蜜蜂</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh</language>
        <lastBuildDate>Thu, 30 Jan 2025 22:39:17 +0800</lastBuildDate><atom:link href="https://xumf.net/tags/spring-refresh/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>Spring 三级缓存</title>
            <link>https://xumf.net/blog/springthridlevelcache/</link>
            <pubDate>Thu, 30 Jan 2025 22:39:17 +0800</pubDate>
            <guid>https://xumf.net/blog/springthridlevelcache/</guid>
            <description>&lt;h2 id=&#34;三级缓存&#34;&gt;三级缓存&#xA;&lt;/h2&gt;&lt;p&gt;在 Spring 框架中，&lt;strong&gt;三级缓存&lt;/strong&gt;机制用于解决单例 Bean 的循环依赖问题。当两个或多个单例 Bean 相互依赖时，Spring 通过三级缓存来确保它们能够相互引用，避免了循环依赖倒置的错误。&lt;/p&gt;&#xA;&lt;h3 id=&#34;三级缓存的组成&#34;&gt;三级缓存的组成：&#xA;&lt;/h3&gt;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;Spring的DefaultSingletonBeanRegistry类三级缓存对象&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;final&lt;/span&gt; Map&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;String, Object&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; singletonObjects &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; ConcurrentHashMap&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;(256);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;final&lt;/span&gt; Map&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;String, Object&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; earlySingletonObjects &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; ConcurrentHashMap&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;(16);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;final&lt;/span&gt; Map&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;String, ObjectFactory&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; singletonFactories &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; HashMap&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;(16);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;一级缓存（&lt;strong&gt;&lt;strong&gt;singletonObjects&lt;/strong&gt;&lt;/strong&gt;）&lt;/strong&gt;：存放完全初始化的单例 Bean 实例。当请求一个 Bean 时，Spring 首先从一级缓存中查找，如果存在，则直接返回实例。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;二级缓存（&lt;strong&gt;&lt;strong&gt;earlySingletonObjects&lt;/strong&gt;&lt;/strong&gt;）&lt;/strong&gt;：存放尚未完全初始化的单例 Bean 实例，通常是指构造函数已执行完毕，但属性尚未填充的 Bean。当 Bean 的构造函数执行完毕后，但属性尚未填充的 Bean。当 Bean 的构造函数执行完毕后，Spring 会将其放入二级缓存中，以便在依赖注入过程中，其它 Bean 可以获取该 Bean 的早期引用，从而解决循环依赖。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;三级缓存（&lt;strong&gt;&lt;strong&gt;singletonFactories&lt;/strong&gt;&lt;/strong&gt;）&lt;/strong&gt;：存放用于创建单例 Bean 的工厂对象（ObjectFactory）。当 Bean 正在创建过程中，且需要提前暴露其引用时，Spring 会将用于创建该 Bean 的工厂对象放入三级缓存中。其它 Bean 在依赖注入时，可以通过三级缓存获取该工厂对象，从而获取正在创建中的 Bean 的引用。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;三级缓存解决下循环依赖的流程&#34;&gt;三级缓存解决下循环依赖的流程&#xA;&lt;/h3&gt;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;实例化 Bean&lt;/strong&gt;：当 Spring 需要创建一个 Bean 时，首先会检查一级缓存中是否已有该 Bean 的实例。如果没有，则开始实例化该 Bean。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;放入三级缓存&lt;/strong&gt;：在实例化过程中，Spring 会将用于创建该 Bean 的工厂对象放入三级缓存中。这样，其它 Bean 在依赖注入时，可以通过三级缓存获取该工厂对象，从而获取到正在创建中的 Bean 的引用。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;放入二级缓存&lt;/strong&gt;：当 Bean 的构造函数执行完毕后，Spring 会将其放入二级缓存中。此时，其它 Bean 可以从二级缓存中获取到该 Bean 的早期引用。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;放入一级缓存&lt;/strong&gt;：当 Bean 的属性填充和初始化方法执行完毕后，Spring 会将其放入一级缓存，表示该 Bean 已完全初始化。此时，其它 Bean 可以从一级缓存中获取到该 Bean 的实例。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;为什么需要三级缓存&#34;&gt;为什么需要三级缓存？&#xA;&lt;/h3&gt;&lt;p&gt;虽然二级缓存可以解决大部分循环依赖问题，但在涉及 AOP（面向切面编程）时，三级缓存显得尤为重要。在 AOP 代理的情况下，Bean 的创建过程需要通过代理工厂来生成代理对象。三级缓存缓存中的工厂对象正是用于创建这些代理对象的。如果没有三级缓存，Spring 将无法在 Bean 创建过程中提前暴露代理对象，从而导致循环依赖无法解决。&lt;/p&gt;&#xA;&lt;p&gt;通过引用三级缓存，Spring 能够在 Bean 创建过程中提前暴露代理对象，确保循环依赖能够正确解决。这使得 Spring 在处理复杂的依赖关系时，能够保持高效和灵活。&lt;/p&gt;&#xA;&lt;p&gt;总之，Spring 的三级缓存机制通过合理的缓存策略，确保了单例 Bean 在存在循环依赖和 AOP 代理的情况下，能够正确地相互引用，避免了循环依赖导致的错误。&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
