本文代码入口:

\spring-framework-5.0.x\spring-beans\src\main\java\org\springframework\beans\factory\support\AbstractBeanFactory.getBean(String name);

* ***PS * 本文仅供学习,如有谬误,感谢指正。***

1. FactoryBean 的使用

bean 比较复杂的时候,需要大量配置信息。

可以通过工厂,定制 bean 的实例化,从而摆脱大量配置信息,灵活性提高。如: class="xx.xxx.FactoryBeanImpl",调用 getBean(beanName),将返回 FactoryBeanImpl.getObject()。

2. 缓存中获取单例 bean;

单例 bean 只会被创建一次,优先从缓存中获取,获取失败,再进入加载流程。(确保容器中只有一个 bean)

3. 从 bean 实例获取对象,

检查 bean 是否为 FactoryBean 类型;若是,FactoryBean调用其 getObject方法,否则返回解析到的 bean。

4. 获取单例 bean (从缓存加载失败);

从 ObjectFactory 获取 bean (回调它的 getObject() 方法,再去调用 creatBean()方法,创建 bean 由子类:spring-beans\src\main\java\org\springframework\beans\factory\support\AbstractAutowireCapableBeanFactory.java提供实现)

java sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { public Object getObject() throws BeansException{ // 准备完成后回调 由子类 AbstractAutowireCapableBeanFactory 实现方法 return createBean(beanName, mbd, args); } }

5. 创建 bean (createBean)

  • a.处理 overrride 属性 lookup-method (策略模式应用,bean替换??) replace-method (动态替换方法的实现)
  • b.实例化前 <后处理器>,

    对 BeanDefinition 的属性做前置化处理,提高拓展能力;

    提供了一个短路逻辑,如果该 <后处理器> 返回值不为空,则直接调用 实例化后 的 <后处理器>,

    并把 通用的 bean 创建环节短路掉。
  • c.实例化后 <后处理器>

6. 循环依赖

  • a. 构造器循环依赖 无法解决
  • b. setter 注入循环依赖 (bean 未创建完毕就将其 ObjectFactory 暴露,当别的bean 依赖他时,

    即使该 bean 尚未完成加载,也可以从缓存中,获取到该提前暴露的 ObjectFactory )
  • c. prototype(原型模式)范围的依赖处理

    该模式 bean spring 容器不会进行缓存,因此无法提前暴露一个 bean

7. 创建 bean

  • a. 单例 bean 先清除缓存,确保 spring 容器中只有一个bean

  • b. 获取 bean 实例

    1. 如果指定了 supplier 属性:那么不通过反射去实例化bean, 而是通过回调 得到对象实例并返回。(面向函数式编程提供回调)

    2. 根据 BeanDefinition 判断是否存在工厂方法,如果存在,调用工厂方法并返回。

    3. 解析构造函数,多个构造函数是,根据 getBean() 入参个数匹配构造函数,否则使用默认构造函数实例化 bean;

  • c. 依赖处理

    根据 bean 是否单例,以及 xml 配置决定是否提前暴露对象

                    单例  && 允许循环依赖   && bean 正在创建   === 是否允许提早曝光
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
    isSingletonCurrentlyInCreation(beanName));
  • e. 属性填充

    1. 给 InstantiationAwareBeanPostProcessors.postProcessAfterInstantiation 最后一次机会,

      通过属性注入改变 bean,它可以控制是否继续对bean进行属性填充。

    2. 根据类型(type)或者 名称(name)注入依赖的bean;

    3. InstantiationAwareBeanPostProcessor.postProcessPropertyValues 对需要依赖检查 的属性,在属性填充前,

      进行后处理器 处理;

    4. 将 PropertyValues [它缓存解析到的当前加载bean依赖的所有bean] 注入到 BeanWrapper[bean的包装器] 中。

  • f. 循环依赖检查

    spring 解决依赖循环只对单例有效,prototype作用范围的bean, spring没有较好的解决办法,只能抛出异常。

  • g. 注册disposableBean

    destory-method 定义的方法,对象销毁时调用。

Spring源码之bean的加载的更多相关文章

  1. 【Spring源码分析系列】加载Bean

    /** * Create a new XmlBeanFactory with the given input stream, * which must be parsable using DOM. * ...

  2. Spring源码解析-配置文件的加载

    spring是一个很有名的java开源框架,作为一名javaer还是有必要了解spring的设计原理和机制,beans.core.context作为spring的三个核心组件.而三个组件中最重要的就是 ...

  3. 五、spring源码阅读之ClassPathXmlApplicationContext加载beanFactory

    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml&q ...

  4. Spring 系列教程之 bean 的加载

    Spring 系列教程之 bean 的加载 经过前面的分析,我们终于结束了对 XML 配置文件的解析,接下来将会面临更大的挑战,就是对 bean 加载的探索.bean 加载的功能实现远比 bean 的 ...

  5. 从SpringBoot源码分析 配置文件的加载原理和优先级

    本文从SpringBoot源码分析 配置文件的加载原理和配置文件的优先级     跟入源码之前,先提一个问题:   SpringBoot 既可以加载指定目录下的配置文件获取配置项,也可以通过启动参数( ...

  6. 05 flask源码剖析之配置加载

    05 Flask源码之:配置加载 目录 05 Flask源码之:配置加载 1.加载配置文件 2.app.config源码分析 3.from_object源码分析 4. 总结 1.加载配置文件 from ...

  7. Spring源码系列 — Bean生命周期

    前言 上篇文章中介绍了Spring容器的扩展点,这个是在Bean的创建过程之前执行的逻辑.承接扩展点之后,就是Spring容器的另一个核心:Bean的生命周期过程.这个生命周期过程大致经历了一下的几个 ...

  8. Spring源码之Bean生命周期

    https://www.jianshu.com/p/1dec08d290c1 https://www.cnblogs.com/zrtqsk/p/3735273.html 总结 将class文件加载成B ...

  9. Spring源码 21 Bean生命周期

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  10. Spring mybatis源码篇章-Mybatis主文件加载

    通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-SqlSessionFactory 前话 本文承接前文的内容继续往下扩展,通过Spring与Mybatis的 ...

随机推荐

  1. [转帖]db file sequential read-数据文件顺序读取

    https://www.cnblogs.com/xibuhaohao/p/9959593.html 等待事件: "db file sequential read" Referenc ...

  2. [转帖]oracle OSWatcher安装部署

    Oswatch是oracle官方提供,用于收集操作系统性能的小工具,oswatch的安装与使用也比较简单,直接解压就可以使用.oswatch是通过调用系统的命令完成信息的收集,如:ps ,top ,m ...

  3. 【JS 逆向百例】webpack 改写实战,G 某游戏 RSA 加密

    关注微信公众号:K哥爬虫,QQ交流群:808574309,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途 ...

  4. 【JS 逆向百例】元素ID定位加密位置,某麻将数据逆向

    声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 逆向目标 目标:某在线麻将 ...

  5. 🛠 开源即时通讯(IM)项目OpenIM源码部署指南

    OpenIM的部署涉及多个组件,并支持多种方式,包括源码.Docker和Kubernetes等.这要求在确保不同部署方式之间的兼容性同时,还需有效管理各版本之间的差异.确实,这些都是复杂的问题,涉及到 ...

  6. 设计模式学习-使用go实现组合模式

    组合模式 定义 适用范围 优点 缺点 代码实现 参考 组合模式 定义 组合模式(Composite),将对象组合成树形结构以表示'部分-整体'的层次关系.组合模式使得用户对单个对象和组合对象的使用具有 ...

  7. 5.10 Windows驱动开发:摘除InlineHook内核钩子

    在笔者上一篇文章<内核层InlineHook挂钩函数>中介绍了通过替换函数头部代码的方式实现Hook挂钩,对于ARK工具来说实现扫描与摘除InlineHook钩子也是最基本的功能,此类功能 ...

  8. Pdfium.Net.Free 一个免费的Pdfium的 .net包装器--PDF预览器框选

    项目地址: Pdfium.Net:https://github.com/1000374/Pdfium.Net PdfiumViewer:https://github.com/1000374/Pdfiu ...

  9. Linux服务器Crontab定时任务配置

    1.检查linux系统是否有crontab rpm -qa | grep crontab 2.如果未安装进行安装 yum -y install vixie-cron yum -y install cr ...

  10. 什么是IO?IO的本质?|如何让IO变得高效?何为高效?|异步IO|多路转接|reactor模式

     前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助. 高质量干货博客汇总https://blog ...