bean的生命周期 || 循环依赖问题 || BeanFactory vs FactoryBean || 自动装配原理

Bean容器

  1. BeanFactory: The root interface for accessing a Spring bean container.
    特点: 延迟初始化 (只有客户端访问BF管理的对象时,才对该对象进行初始化操作和DI)
    使用场景: 容器启动较快,所需资源比较少
  2. ApplicationContext : 继承BF
    在这里插入图片描述
    特点: 更加完善,提供了其他的高级特性:事件发布,国际化信息支持等
    使用场景: 系统资源充足,功能需求更多的场景中(目前使用较多)

SpringIOC

在 Spring 框架中,IOC(Inversion of Control,控制反转)是一种设计原则和编程范式,它通过将对象的创建和依赖关系的管理交给容器来实现,从而实现对象之间的解耦和灵活性。
在传统的编程模式中,对象之间的依赖关系通常是硬编码在代码中的,当一个对象需要使用另一个对象时,它必须直接创建或查找该对象。这样导致了对象之间紧密耦合,难以维护和扩展。
而在 Spring 中,IOC 容器扮演了一个重要的角色。它负责管理应用程序中的所有 Bean(对象),包括创建和销毁它们,并通过依赖注入(Dependency Injection,DI)的方式将对象之间的依赖关系自动注入到相应的 Bean 中。
具体来说,IOC 实现了以下几个核心概念:

  • Bean 定义:在 Spring 中,每个对象都被称为一个 Bean。Bean 定义描述了对象的创建和配置信息,通常在 XML
    文件中进行配置。

  • IOC 容器:IOC 容器负责解析 Bean 的定义,并负责创建、管理和维护 Bean 的生命周期。Spring
    提供了不同类型的 IOC 容器,最常见的是 ApplicationContext。

  • 依赖注入(DI):IOC容器通过依赖注入的方式将对象之间的依赖关系注入到相应的 Bean 中。这样,在创建一个对象时,它所依赖的其他对象会自动被注入到它里面。
    通过使用 IOC,开发者只需关注对象本身的实现,而无需关心对象之间的创建和管理过程,大大简化了代码的编写和维护。同时,IOC 也提高了代码的可测试性和可扩展性,因为对象之间的耦合度降低,可以轻松替换和调整 Bean 的配置。

Bean对象的生命周期

在这里插入图片描述

讲一下Bean的生命周期

spring是一个轻量级的框架,为了帮助我们进行简化开发,里面最核心的功能有IOC和AOP,Bean的生命周期只是IOC创建对象中的流程,大体上包括实例化,初始化,使用和销毁四个部分,这是粗粒度的一个描述。
那么从细粒度的角度上来说,先从实例化开始,通过反射的方式读取到BD中的相关信息,可以把对应的class对象创建出来,可以通过反射的方式加载我们的类并且创建出当前对象,此时的创建只是在堆空间中申请了一块内存空间,并没有实际的给对象进行复制,所以此时对象的属性是默认值的,当默认值结束后,会通过PopulateBean对我们的当前对象进行属性赋值操作,会调用对应的set方法完成属性的赋值,但是在这个步骤里面只是完成了自定义属性赋值的操作,还有一部分属性叫做容器属性,也就是再Spring框架中,他自己帮我们定义的一些类对象,我们自定义的对象中也可能会使用这些容器对象,所以对容器对象进行赋值的时候需要调用Aware接口,通过Aware接口的判断确定出是否能够进行属性值的设置工作,所以相当于PopulateBean和InvokeAwareMethods共同完成了对象的初始化工作。一个是自定义属性的赋值,一个是容器属性的赋值,当这个步骤执行成功之后,按照正常情况我们的Bean对象已经能够正常使用了,但是Spring是一个框架,他在进行设置时需要考虑一个特点:可扩展性,当bean对象创建完成后,可能有一些对Bean对象进行扩展的过程,比如说AOP的实现,其实就是对我们的Bean对象的一个扩展操作,因此在这个时候,会在BeanPostPocessor()对接口的after或者Before方法来进行一些相关的扩展操作,比如说AOP动态代理的实现就是在after方法里面实现的,而在Before和After方法中间,还有一个初始化方法的调用,这个初始化方法一般情况下是不进行使用的,但是这里面有一个非常重要的隐藏接口,叫initlizationBean,在这个接口里面,会给我们正在创建的对象留一个afterPropertySet方法,这个方法会给用户最后一次机会来完成一些属性和方法的调用,留给用户自己的空间,当这些步骤都执行完成之后,我们整个对象就已经创建结束了,那么现在我们就可以通过Context.GetBean方法来进行对象地使用了,当对象使用完毕后,在关闭容器的时候,会调用close方法,来把我们创建的对象进行销毁。

创建class对象的三种方式:1. 类.calss 2. Class.forName(类路径)3. 类名.getclass()
Spring创建对象和销毁对象的时机

循环依赖

Spring是如何解决的循环依赖

Spring通过三级缓存解决了循环依赖,其中一级缓存为单例池(singletonObjects),二级缓存为早期曝光对象earlySingletonObjects,三级缓存为早期曝光对象工厂(singletonFactories)。当A、B两个类发生循环引用时,在A完成实例化后,就使用实例化后的对象去创建一个对象工厂,并添加到三级缓存中,如果A被AOP代理,那么通过这个工厂获取到的就是A代理后的对象,如果A没有被AOP代理,那么这个工厂获取到的就是A实例化的对象。当A进行属性注入时,会去创建B,同时B又依赖了A,所以创建B的同时又会去调用getBean(a)来获取需要的依赖,此时的getBean(a)会从缓存中获取,第一步,先获取到三级缓存中的工厂;第二步,调用对象工工厂的getObject方法来获取到对应的对象,得到这个对象后将其注入到B中。紧接着B会走完它的生命周期流程,包括初始化、后置处理器等。当B创建完后,会将B再注入到A中,此时A再完成它的整个生命周期。至此,循环依赖结束!

为什么要使用三级缓存呢?二级缓存能解决循环依赖吗?

答:如果要使用二级缓存解决循环依赖,意味着所有Bean在实例化后就要完成AOP代理,这样违背了Spring设计的原则,Spring在设计之初就是通过AnnotationAwareAspectJAutoProxyCreator这个后置处理器来在Bean生命周期的最后一步来完成AOP代理,而不是在实例化后就立马进行AOP代理

BeanFactory & FactoryBean

  • BeanFactory
    工厂,用于对象的创建,要经过一个完整的复杂的生命周期的处理过程
    (Bean的生命周期,一个流水线的过程)
  • FactoryBean
    Bean: 特殊的对象创建,假设这个对象只需要再某一个方法中用—次,使用完整的生命周期很麻烦,所以有了更加简单的方式
    (私人定制)

在这里插入图片描述

  • isSingleton: 判断当前对象是否是单例对象
  • getObjectType:返回创建的对象的类型
  • getObject:根据用户自定义的方式来选择对象的创建
  1. new
  2. 反射
  3. 动态代理

自动装配原理

在这里插入图片描述

讲一下自动装配的流程

自动装配简单来说就是自动把第三方jar 包中的Bean装配到IOC容器中,不需要开发人员再去写Bean相关的配置,在springboot框架的应用里面,只需要在启动类上加上@springbootApplication注解就可以实现自动装配,springbootApplication这样的注解是一个复合注解,真正去实现自动装配的注解是@EnableAutoConfiguration这样一个注解,自动装配的实现主要依靠三个核心的关键技术

  • 引入Starter启动依赖组件的时候,组件必须包含一个@Configuration配置类,而在这个配置类里面我们需要通过@Bean这个注解去声明需要装配到IOC容器里的Bean对象
  • 通过SpringBoot中”约定优于配置“这样的一个理念,去把这个配置类的全路径放在 classpath:/META-INF/Spring.factories文件里面,这样的话SpringBoot就可以知道第三方jia包里面这个配置类的位置,这个步骤主要是用到了Spring里面的SpringFactoriesLoader 来完成的。
  • SpringBoot拿到所有的第三方jar包里面声明的配置类以后,通过Spring提供的importSelector这样一个接口来实现对这些配置类的动态加载,从而完成自动装配这样一个动作
    在我看来呢,SpringBoot是"约定优于配置"这一理念下的产物,所以在很多的地方都会看到这一思想,他的出现让开发人员可以更加的聚焦在业务代码的编写上,而不需要去关心和业务无关的配置
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值