Spring篇(2)--Spring IOC基本流程原理

本文详细解读Spring IoC的工作原理,包括控制反转和依赖注入,主要流程涉及BeanFactory创建步骤、Bean的初始化过程以及解决循环依赖机制。通过实例阐述了BeanFactory创建、Bean定义解析和注册,以及懒加载和循环依赖的处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 一、Spring IOC是什么


  •  IOC:控制反转,是一种设计模式。
  • 一层含义是控制权的转移,由传统的在程序中控制依赖转移到由容器来控制。
  • 第二层是依赖注入:将相互依赖的对象分离,在Spring配置文件中描述他们的依赖关系,他们的依赖关系只在使用的时候才建立,简单来说就是不需要的NEW一个对象了。

控制反转是反转的什么?

1)传统模式控制权在开发者手中

2)IoC 模式控制权从开发者转移到容器,开发者不再需要手动管理对象间的依赖。

二、流程介绍:


Spring IoC 容器初始化的关键环节就在 AbstractApplicationContext#refresh() ⽅法中

@Override
publicvoidrefresh()throwsBeansException,IllegalStateException{
    synchronized(this.startupShutdownMonitor){
        StartupStepcontextRefresh=this.applicationStartup.start("spring.context.refresh");

        //刷新前的预处理
        //Preparethiscontextforrefreshing.
        prepareRefresh();

        //BeanFactory创建流程一:获取BeanFactory;默认实现是DefaultListableBeanFactory 
        //加载BeanDefition 并注册到 BeanDefitionRegistry
        //Tellthesubclasstorefreshtheinternalbeanfactory.
        ConfigurableListableBeanFactorybeanFactory=obtainFreshBeanFactory();

        //BeanFactory创建流程二:BeanFactory的预准备⼯作(BeanFactory进⾏⼀些设置,⽐如context的类加载器等)
        //Preparethebeanfactoryforuseinthiscontext.
        prepareBeanFactory(beanFactory);

        try{
            //BeanFactory创建流程三:BeanFactory准备⼯作完成后进⾏的后置处理⼯作
            //Allowspost-processingofthebeanfactoryincontextsubclasses.
            postProcessBeanFactory(beanFactory);

              StartupStepbeanPostProcess=this.applicationStartup.start("spring.context.beans.post-process");

            //BeanFactory创建流程四:实例化并调⽤实现了BeanFactoryPostProcessor接⼝的Bean
            //Invokefactoryprocessorsregisteredasbeansinthecontext.
            invokeBeanFactoryPostProcessors(beanFactory);

            //Bean创建流程一:注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执⾏
            //Registerbeanprocessorsthatinterceptbeancreation.
            registerBeanPostProcessors(beanFactory);
            beanPostProcess.end();

            //初始化资源、事件、监听流程一:初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
            //Initializemessagesourceforthiscontext.
            initMessageSource();

            //初始化资源、事件、监听流程二:初始化事件派发器
            //Initializeeventmulticasterforthiscontext.
            initApplicationEventMulticaster();

            //初始化资源、事件、监听流程三:⼦类重写这个⽅法,在容器刷新的时候可以⾃定义逻辑
            //Initializeotherspecialbeansinspecificcontextsubclasses.
            onRefresh();

            //初始化资源、事件、监听流程四:注册应⽤的监听器。就是注册实现了ApplicationListener接⼝的监听器bean
            //Checkforlistenerbeansandregisterthem.
            registerListeners();

            //Bean创建流程二:初始化所有剩下的⾮懒加载的单例bean
            //Instantiateallremaining(non-lazy-init)singletons.
            finishBeanFactoryInitialization(beanFactory);

            //完成context的刷新。主要是调⽤LifecycleProcessor的onRefresh()⽅法,并且发布事件 (ContextRefreshedEvent)
            //Laststep:publishcorrespondingevent.
            finishRefresh();
    }

    catch(BeansExceptionex){
          if(logger.isWarnEnabled()){
           logger.warn("Exceptionencounteredduringcontextinitialization-"+
"cancellingrefreshattempt:"+ex);
    }

        //Destroyalreadycreatedsingletonstoavoiddanglingresources.
        destroyBeans();

        //Reset'active'flag.
        cancelRefresh(ex);

        //Propagateexceptiontocaller.
        throwex;
    }

    finally{
        //ResetcommonintrospectioncachesinSpring'score,sincewe
        //mightnoteverneedmetadataforsingletonbeansanymore...
        resetCommonCaches();
        contextRefresh.end();
    }
}
}

可以看到会有以下主流程:

主要有几大模块:

(1)执行前的预处理与执行后的context刷新

(2)BeanFactory创建流程

(3)Bean创建流程

(4)初始化资源、事件、监听流程

执行顺序如下:

(1)刷新前的预处理(配置环境参数、创建监听器、事件容器)

(2)BeanFactory创建流程一:获取BeanFactory(默认实现是DefaultListableBeanFactory) ,加载BeanDefition 并注册到 BeanDefitionRegistry

(3)BeanFactory创建流程二:BeanFactory的预准备⼯作(BeanFactory进⾏⼀些设置,⽐如context的类加载器等)

(4)BeanFactory创建流程三:BeanFactory准备⼯作完成后进⾏的后置处理⼯作

(5)BeanFactory创建流程四:实例化并调⽤实现了BeanFactoryPostProcessor接⼝的Bean

(6)Bean创建流程一:注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执⾏

(7)初始化资源、事件、监听流程一:初始化MessageSource组件(做国际化功能;消息绑定,消息解析)

(8)初始化资源、事件、监听流程二:初始化事件派发器

(9)初始化资源、事件、监听流程三:⼦类重写这个⽅法,在容器刷新的时候可以⾃定义逻辑

(10)初始化资源、事件、监听流程四:注册应⽤的监听器。就是注册实现了ApplicationListener接⼝的监听器bean

(11)Bean创建流程二:初始化所有剩下的⾮懒加载的单例bean

(12)完成context的刷新。主要是调⽤LifecycleProcessor的onRefresh()⽅法,并且发布事件 (ContextRefreshedEvent)

三、BeanFactory创建流程


1.获取BeanFactory

时序图如下:

2.BeanDefinition加载解析及注册

主要有以下几步:

1Resource定位:指对BeanDefinition的资源定位过程。通俗讲就是找到定义Javabean信息的XML⽂件,并将其封装成Resource对象。

过程:

⼦流程⼊⼝在 AbstractRefreshableApplicationContext#refreshBeanFactory ⽅法中

依次调⽤多个类的 loadBeanDefinitions ⽅法 ​ —> AbstractXmlApplicationContext ​ —>AbstractBeanDefinitionReader —> XmlBeanDefinitionReader ​ ⼀直执⾏到XmlBeanDefinitionReader 的doLoadBeanDefinitions ⽅法

doLoadBeanDefinitions()方法主要内容是:读取xml,将xml中的信息保存到Document对象,并解析document对象,封装BeanDefinition对象并注册

2BeanDefinition载⼊ :把⽤户定义好的Javabean表示为IoC容器内部的数据结构,这个容器内部的数据结构就是BeanDefinition。

主要是XmlBeanDefinitionReader 类的 registerBeanDefinitions ⽅法(在上述doLoadBeanDefinitions()方法中)会最终调用到DefaultBeanDefinitionDocumentReader中的processBeanDefinition方法

bdHolder=delegate.decorateBeanDefinitionIfRequired(ele,bdHolder);为解析成BeanDefintionHolder对象

3)注册BeanDefinition IoC 容器

接着上述的DefaultBeanDefinitionDocumentReader中的processBeanDefinition方法

BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder,getReaderContext().getRegistry());为完成注册操作

所谓的注册就是把封装的 XML 中定义的 Bean信息封装为BeanDefinition 对象之后放⼊⼀个Map中,BeanFactory 是以 Map 的结构组织这些 BeanDefinition的。

四、Bean创建流程


备注:

1.lazy-init 延迟加载机制

普通 Bean 的初始化是在容器启动初始化阶段执⾏的,⽽被lazy-init=true修饰的 bean 则是在从容器⾥第⼀次进⾏context.getBean() 时进⾏触发。

(1)对于被修饰为lazy-init的bean Spring 容器初始化阶段不会进⾏ init 并且依赖注⼊,当第⼀次进⾏getBean时候才进⾏初始化并依赖注⼊

(2)对于⾮懒加载的bean,getBean的时候会从缓存⾥头获取,因为容器初始化阶段 Bean 已经初始化完成并缓存了起

2.Spring IoC循环依赖问题

循环依赖其实就是循环引⽤,也就是两个或者两个以上的 Bean 互相持有对⽅,最终形成闭环。

Spring中循环依赖场景有:

  • 构造器的循环依赖(构造器注⼊)
  • Field 属性的循环依赖(set注⼊)

循环依赖无法处理的情况

  • 单例 bean 构造器参数循环依赖(⽆法解决)
  • prototype 原型 bean循环依赖(⽆法解决)

Spring中解决循环依赖的过程

(1)BeanA对象在实例化之后立马放入三级缓存

(2)BeanB在创建过程中发现依赖A,那么去三级缓存使用尚未成型的BeanA

(3)将BeanA升级放到二级缓存

(4)BeanB创建完成之后会放入一级缓存

(5)BeanA使用一级缓存中的BeanB

备注:

(1)singletonObjects:一级缓存,存储的是所有创建好了的单例Bean。(解决AOP)

(2)earlySingletonObjects:二级缓存,完成实例化,但是还未进行属性注入及初始化的对象(解决对象完整性)

(3)singletonFactories:三级缓存,暴露的一个单例工厂,二级缓存中存储的就是从这个工厂中获取到的对象。(解决循环依赖)

 更多内容:

Spring篇(1)--SpringBoot是什么?原理是怎么样的?

Spring篇(2)--Spring IOC基本流程原理

Spring篇(3)--Spring Aop基本流程原理

Spring篇(4-1)--Spring Bean 是什么及其生命周期阶段

Spring篇(4-2)--Spring BeanFactory与FactoryBean 区别

Spring篇(5-1)--Spring事务流程原理

Spring篇(5-2)--Spring事务传播行为

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sun cat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值