mybatis3源码深度解析pdf下_源码深度解析spring的循环引用(一)——生命周期

论坛 期权论坛     
选择匿名的用户   2021-5-23 22:49   160   0
<div>
<p></p>
<div style="text-align:center;">
  <img alt="4524eaee1a8f69622fc350abf265afb3.png" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-e569f968f7027ffb4a6b2a199aeb26a3.png">
</div>
<h2>前言</h2>
<blockquote>
  <b>我是子路,一个把Java当饭吃的人。</b>
</blockquote>
<p>笔者之前在华南谷歌搬砖,在系统架构设计、分布式、微服务、高并发、高可用等技术架构具有丰富的实战经验。对市面上主流的开源框架源码——spring、nacos,springboot、JDK并发工具等等都有深入的研究。</p>
<p>Spring是Java语言里面一个非常重要的框架,可以说任何一个学Java的人都必须要接触到Spring。</p>
<p>这里笔者先给大家好好从源码的角度来讲讲Spring。</p>
<h2>正文</h2>
<p>众所周知spring在默认单例的情况下是支持循环引用的</p>
<p>为了节省图片大小我把那些可以动的gif图片做成了只循环一次,如果看到图片不动了请右键选择在新标签打开,那么图片就会动,手机用户则更简单,直接手指点击图片便能看到动图,每张gif我都标识了,如果没有标识则为静态图片;</p>
<p>Appconfig.java类的代码</p>
<div class="blockcode">
  <pre class="blockcode"><code>&#64;Configurable
&#64;ComponentScan(&#34;com.shadow&#34;)
public class Appconfig {}</code></pre>
</div>
<p>X.java类的代码</p>
<div class="blockcode">
  <pre class="blockcode"><code>package com.shadow.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
&#64;Component
public class X {
    &#64;Autowired
    Y y;    public X(){
        System.out.println(&#34;X create&#34;);
    }}</code></pre>
</div>
<p>Y.java类的代码</p>
<div class="blockcode">
  <pre class="blockcode"><code>package com.shadow.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
&#64;Component
public class Y {
    &#64;Autowired
    X x;    public Y(){
        System.out.println(&#34;Y create&#34;);
    }}</code></pre>
</div>
<p>这两个类非常简单,就是相互引用了对方,也就是我们常常的说的循环依赖,spring是允许这样的循环依赖(前提是单例的情况下的,非构造方法注入的情况下)</p>
<p><b>运行这段代码的结果下图</b></p>
<blockquote>
  注意这是张gif,如果你看着不动请参考我上面说的方法
</blockquote>
<p></p>
<div style="text-align:center;">
  <img alt="00a508347baa35909cc18aa48d72847a.png" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-163fd27b55b84c0a5bf49576f97755b6.png">
</div>
<p>上面代码从容器中能正常获取到Xbean,说明循环依赖成功。但是spring的循环依赖其实是可以关闭的,spring提供了api来关闭循环依赖的功能。当然你也可以修改spring源码来关闭这个功能,这里笔者为了提高逼格,就修改一下spring的源码来关闭这个功能,老话说:要想高明就得ZB。</p>
<p><b>下图是我修改spring源码运行的结果</b></p>
<p>我在AnnotationConfigApplicationContext的构造方法中加了一行setAllowCircularReferences(false);结果代码异常,循环依赖失败:</p>
<p></p>
<div style="text-align:center;">
  <img alt="61767ddf594c479cde624247e1fad646.png" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-8159fe26ca05fb6803c0b80bc5618050.png">
</div>
<p>那么为什么setAllowCircularReferences(false);会关闭循环依赖呢?首要明白spring的循环依赖是怎么做到的呢?spring源码当中是如何处理循环依赖的? 分析一下所谓的循环依赖其实无非就是属性注入,或者就是大家常常说的自动注入, 故而搞明白循环依赖就需要去研究spring自动注入的源码;spring的属性注入属于spring bean的生命周期一部分;怎么理解spring bean的生命周期呢?注意笔者这里并不打算对bean的生命周期大书特书,只是需要读者理解生命周期的概念,细节以后在计较;</p>
<p>要理解bean的生命周期首先记住两个概念——spring bean(以下简称bean)和对象:</p>
<p><b>1、spring bean</b>——受spring容器管理的对象,可能经过了完整的spring bean生命周期(为什么是可能?难道还有bean是没有经过bean生命周期的?答案是有的,具体我们后面文章分析),最终存在spring容器当中;一个bean一定是个对象。</p>
<p><b>2、对象</b>——任何符合java语法规则实例化出来的对象,但是一个对象并不一定是spring bean。</p>
<p>所谓的bean的生命周期就是磁盘上的类通过spring扫描,然后实例化,跟着初始化,继而放到容器当中的过程;</p>
<p>我画了一张简单图来阐述一下spring bean的生命周期大概有哪些步骤:</p>
<p></p>
<div style="text-align:center;">
  <img alt="edf8ee90c3cfb641b30b428689b990b6.png" src="https:/
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP