小明学Spring基础系列——Bean的生产

1. 前言

Spring的核心特性就是控制反转(IOC)和切面编程(AOP),Spring通过IOC容器来实现这些特性,IOC容器中,用户定义的对象以Bean的形式存放,然后由Spring解决Bean之间的依赖关系,并且对Bean进行代理从而实现AOP编程。Spring中的Bean由BeanFactory生产,生产流程比较复杂,因为在生产过程中需要解决Bean之间的依赖、Bean的作用域、Bean的实例化前后处理、Bean的初始化前后处理等步骤,最后才能得到一个装配完全的Bean。本文的重点就是讲述一下Bean的生产流程,其中涉及到的BeanFactory、BeanPostProcessor等概念不做详细介绍。 Spring的Bean生产流程中的关键环节如下图所示:
在这里插入图片描述

2. 生产Bean的主要步骤

Spring生产Bean的过程就是将Spring中的Bean定义转为对应SpringBean实体,关于SpringBean定义我会在其它博客中详细介绍,Bean定义会在Spring容器启动的最初环节通过xml定义文件或者扫描注解注册到容器的缓存中,那么Spring的Bean定义是在什么时候转为Bean的实体的呢?通常是在调用容器的getBean方法的时候进行实例化的,比如Spring容器启动最后环境会通过getBean初始化所有的非懒加载的单例Bean。那么Spring的getBean流程生怎么样的,内部是怎么样工作的呢?Spring getBean方法的流程主要有以下步骤:

  1. 校验BeanFactory的状态是激活状态,比如在@PreDestory中方法中调用getBean,这个时候容器已经处于销毁环节,会销毁容器中的Bean,这个时候再getBean会有并发问题,因此需要抛出异常,下面为校验容器状态的源码(部分容器不需要校验状态,如可重复Refresh的容器)。
    protected void assertBeanFactoryActive() {
   
        if (!this.active.get()) {
   
            if (this.closed.get()) {
   
                throw new IllegalStateException(getDisplayName() + " has been closed already");
            }
            else {
   
                throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
            }
        }
    }
  1. 解析Bean的名称,Spring中,每个Bean的定义都有一个唯一的名称,同时有很多别名,我们在getBean的时候,可以安装别名、Bean名称和Bean的类来获取Bean,三种类型的参数最终都需要转为Bean的名称才能进行getBean的下一步。
  2. 单例模式解决循环依赖的缓存模型,Spring通过三级缓存解决单例Bean的循环依赖问题,其它作用域的Bean不允许出现循环依赖,否则会抛出异常。
  3. 双亲委派模型,Spring的容器之间允许有父子继承关系,子容器在getBean的环节会先把需要加载的Bean委托给父类加载,父类加载失败再由子类加载,类似于java的类加载模型,所以此处起名叫双亲委派模型。
  4. Bean定义的合并,Spring的Bean定义也允许有父子继承关系,在创建Bean的时候需要将父子Bean的定义合并为一个Bean,方便后续创建Bean
  5. Bean的实例化和初始化,这个阶段包含反射生成bean,并调用实例化前置后置处理方法、BeanPostProcessor方法、自动装配和初始化方法等。

3. Bean名称的解析

前文中我们说过,Spring在getBean的第一步必须要获取到Bean的名称,而Spring的getBean方法可以有三种类型的参数:Bean的别名、Bean的名称和Bean的类型,其中Bean的名称不需要进一步解析,但是Bean的别名和Bean的类型都需要解析为Bean的名称才能继续往下走。本节的重点内容就是Bean别名、工厂Bean和Bean类型解析为Bean的名称的过程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

-御狐神-

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

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

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

打赏作者

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

抵扣说明:

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

余额充值