Spring中Bean实例创建过程

Posted 踩踩踩从踩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring中Bean实例创建过程相关的知识,希望对你有一定的参考价值。

IOC容器核心流程_踩踩踩从踩的博客-CSDN博客

Spring中Bean定义加载过程解析_踩踩踩从踩的博客-CSDN博客

前言

本篇文章之前的文章在解析了spring中bean定义的解析及加载,以及 整个spring框架上的ioc的流程,本篇文章会说到一个重要的概念就是beanfactory  ,我们面试时一般会问到spring,而spring离不开的就是ioc容器而ioc容器最重要的概念就是beanfactory接口,因为他是暴露给外面使用的方法,所有的实例创建 都会离不开 这个东西。本篇文章会继续解析spring框架,搞清楚ApplicationContext实例化Bean的过程,这个过程中涉及的核心类,楚IOC容器提供的扩展点有哪些,学会扩展,IOC容器这里使用的设计模式,不同创建方式的bean的创建过程

实例创建流程

在spring中bean实例的创建是怎么样的,如何实现都是从下面进行深入。

  • 实例化bean创建的流程,先确定创建Bean的入口是不是在getBean方法 是在那里的?

ApplicationContext context = new GenericXmlApplicationContext ( "classpath:/application.xml" ); context . getBean ( "lad" );

这个入口  是利用 context去获取bean的方式,而所有的bean 当然不是采用这种方式去获取bean的。

  • 在什么时候就开始了Bean的初始化?单例Bean能不能提前初始化好?
单例 Bean 提前初始化好,能提高使用时的效率。原型 Bean 则是在 getBean 的时候。 单例和原型 Bean的实例化过程 没区别。都是 getBean(beanName) 。在启动时提前实例化单例 bean ,也是 getBean 单例 bean 的提前初始化在哪里开启的,看看它的代码。
  • Spring中支持的bean实例创建方式有几种?分别如何配置的,如何来获取Bean实例的?

其实创建bean实例的方式有四种。 包括构造方式  工厂方法  指定工厂方法

其实还有一种方式 Factorybean的方式,在使用时  可以 创建  适用在一些外部的组件的集成,是非常好用的。

在applicationcontext中 初始化bean实例,  判断 bean定义的类型 是否可以混合 ,参数是否达到,通过环境嵌套解析出来。

 最后预实例化bean。

这里就判断是不是factorybean  ,对于factorybean  的方式,带有前缀的。 

 

最后还是交给getbean进行获取bean。  包括了一些初始化接口。 这里进来 到父类的 dogetbean方法。

 针对别名的情况,通过 transformedbeanName方法 就可以获取到 beanName,最终判断。 

继续dogetbean中 首先从单例Bean中获取

  •  单例bean不直接返回,当前的bean有可能是工厂bean,Object需要从工厂bean中获取

  • 构造时的循坏依赖的检查
  • 判断是否有父工厂,父工厂不为空,本地又不包含该bean定义,从父工厂中获取
  • 如果不仅仅是做类型检查,记录该bean已经被创建了  

获得合并(父子关系)的bean定义,bean的依赖检查,先创建依赖的bean实例
  • Scope的处理:单例、原型、其他   创建bean实例
  • 在 单例 原型 和其他都会调用 getobjectforbeaninstance 获取bean实例。仍然进行一次工厂bean处理

  • 多例bean的循环依赖的检查处理,并记录  

         多例Bean的处理

               不做存放

              循环依赖的检查与记录释放               记录存放的类型 ThreadLocal          Scope Bean的获取                 存放在Scope中                 Scope接口的定义与实现,策略模式应用                 SimpleThreadScope存放在ThreadLocal

  •  最后怎么创建bean 所有的都通过 createbean方法。

 

解析的点,复制bean定义,解析 beanpostprocessor .给BeanPostProcessor一个创建代理对象的机会,深入方法探查实现  应用InstantiationAwareBeanPostProcessor,bean实例化前后的回调接口

 

在实例化之前就会调用 对应的bean注册 增强 接口进行调用。 到后面 要做的是,docreatebean .怎么去创建bean 真正执行bean对象创建的方法

交给postprocess,应用bean定义的处理。InstantiationAwareBeanPostProcessor

适配器类 InstantiationAwareBeanPostProcessorAdapter 适用点: CGLIB ,来完成实例创建,可以避免创建两个实例。 AbstractAutowireCapableBeanFactory#doCreateBean ,MergedBeanDefinitionPostProcessor的处理,混合处理bean父子类型 急切地缓存单例,以便能够解析循环引用,即使是由生命周期接口触发的,如 BeanFactoryAwares。

 包括属性的判断  初始化 的处理。

解决构造函数的循环依赖。

AbstractAutowireCapableBeanFactory#createBeanInstance

 这里面的逻辑  使用最简单的无参构造函数  

工厂 方法  静态工厂方法  等等 创建 具体的实例的方式。

提前准备单例到beanfacotry 到bean.

包括beanfacotrypostprocessor 、beanpostprocessor  

beandefinitionregirsterpostprocessor.    

针对不同范围的bean的创建模式,单例 多例 scope. 这里 针对的

 根据不同的 session 或者request创建一个bean的方式。

对于不同的bean是不同的创建的。

然后在进去的createbean方法  进去的 docreatebean  这里面 有 个缓存 实例先  移除掉 

AbstractAutowireCapableBeanFactory #createBean(String, RootBeanDefinition, Object[])

看着往里面走, 包括判断 什么 bean类型 

AbstractAutowireCapableBeanFactory #doCreateBean AbstractAutowireCapableBeanFactory #createBeanInstance 这在源代码中继续下去看。

 单例bean,并不是原生的bean,做了很多扩展,暴露的对象,实例化bean对象。

初始化动作之前,属性填充 ,这里 populatebean  就是做的这个操作,

 

 这里涉及到 依赖注入的东西。

 以及  这里  做的  初始化前 做的  涉及到 aop 的前置增强。

  初始化方法,这也是经过了前置准备操作,才开始的 初始化  方法

 这里 涉及到 三个接口 包括 initiazingbean   以及 销毁的disposablebean  接口的

关于bean的生命周期会用到的接口。

属性给完过后。 这在之前 分析Scheduled 任务都会遇到的。 一些 

spring源码深入理解 (一): 定时任务-自定义注解及任务及同一时间多任务执行_踩踩踩从踩的博客-CSDN博客 MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition AbstractAutowireCapableBeanFactory #populateBean AbstractAutowireCapableBeanFactory#initializeBean(String, Object, RootBeanDefinition) AbstractBeanFactory#registerDisposableBeanIfNecessary 然后就是后置增强 注入 的销毁bean,并最终的返回bean操作了。  

 接口  也就是容器关闭后 对工厂的销毁方法。

然后接下来继续说说 createbeaninstance 方法创建bean实例

首先 获取bean的类型。

这里创建 bean实例的时候,这里就开始 根据参数判断  调用那个方式进行创建bean.

包括 bean定义中,还会根据 参数  args时去判断。 

 

// 通过指定的提供者实现实例创建 AbstractAutowireCapableBeanFactory#obtainFromSupplier // 通过工厂模式实现实例创建 AbstractAutowireCapableBeanFactory#instantiateUsingFactoryMethod // 通过(指定的参数:配置、实参)匹配到相对应的构造函数,实现实例创建 AbstractAutowireCapableBeanFactory#autowireConstructor // 通过无参构造函数创建实例 AbstractAutowireCapableBeanFactory#instantiateBean

 

 根据beanname的class 去判断到底是走那条路

 

那个方法和参数可以使用的。 构造定义工厂方法参数。匹配工厂方法  这里判断 无参  有参 等的配置。 数量 类型等的匹配。 优先 bean定义的函数  

 

以上是关于Spring中Bean实例创建过程的主要内容,如果未能解决你的问题,请参考以下文章

spring中bean创建过程中的扩展点

spring中bean创建过程中的扩展点

Spring源码浅析之bean实例的创建过程

Spring IOC 容器源码分析 - 创建单例 bean 的过程

Spring IOC 容器源码分析 - 创建单例 bean 的过程

spring中的“bean”有啥用处?