一步步Debug源码,带你了解Spring如何解决依赖循环

举报
dfsafdfas 发表于 2021/01/27 12:43:17 2021/01/27
2.6k+ 0 0
【摘要】 1、流程步骤概述(说出来,我就不信面试敢说你没看过源码)基本的核心流程: getBean->doGetBean->getSingleton->createBean->doCreateBean->createBeanInstance->addSingletonFactory->populateBean->applyPropertyValues->resolveValueNecessary->r...

1、流程步骤概述

(说出来,我就不信面试敢说你没看过源码)

基本的核心流程: getBean->doGetBean->getSingleton->createBean->doCreateBean->createBeanInstance->addSingletonFactory->populateBean->applyPropertyValues->resolveValueNecessary->resolveReference

具体的流程请看下面的流程讲解。

2、代码流程详解。

2.0、测试案例


public class A {

    @Autowired
    private B b;

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }
}

----------------------------------------------------------------------------------------------------------------

public class B {

    @Autowired
    private A a;

    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }
}

----------------------------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="a" class="com.ytao.domain.A">
        <property name="b" ref="b"></property>
    </bean>

    <bean id="b" class="com.ytao.domain.B">
        <property name="a" ref="a"></property>
    </bean>

</beans>

----------------------------------------------------------------------------------------------------------------
public static void main(String[] args) {

        ApplicationContext config = new ClassPathXmlApplicationContext("spring.xml");
        B b = (B) config.getBean("b");
        System.out.println("b对象为"+b.getA());
        A a = (A) config.getBean("a");
        System.out.println("a对象为"+a.getB());
    }

----------------------------------------------------------------------------------------------------------------

输出结果:
A对象为com.ytao.domain.A@1c9b0314
22:26:16.439 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'a'
B对象为com.ytao.domain.B@45385f75

2.1、第一轮循环getBean代码流程讲解

在讲的Spring的时候,此时我们必会看一个方法那就是refresh。它里面包含了Bean初始化的操作。在类
AbstractApplicationContext中的finishBeanFactoryInitialization 包含了spring容器中bean的创建流程。

在这里插入图片描述

此时我们进入了finishBeanFactoryInitialization,经过前面代码一些我们不关注的代码,我们直接走到相关创建bean逻辑代码 beanFactory.preInstantiateSingletons();,从在这里看才开始正儿八经的实例化
在这里插入图片描述

进入到了preInstantiateSingletons,同理我们直接关注创建bean的代码逻辑来到了this.getBean(beanName) ->doGetBean 。 注意这里它先遍历的是对象A

在这里插入图片描述
然后debug进入getBean -> doGetBean,在这里我们看到了有根据className获取实例的代码Object sharedInstance = getSingleton(beanName);

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。