Spring源码之bean的加载
本文代码入口:
\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 实例
如果指定了 supplier 属性:那么不通过反射去实例化bean, 而是通过回调 得到对象实例并返回。(面向函数式编程提供回调)
根据 BeanDefinition 判断是否存在工厂方法,如果存在,调用工厂方法并返回。
解析构造函数,多个构造函数是,根据 getBean() 入参个数匹配构造函数,否则使用默认构造函数实例化 bean;
c. 依赖处理
根据 bean 是否单例,以及 xml 配置决定是否提前暴露对象
单例 && 允许循环依赖 && bean 正在创建 === 是否允许提早曝光
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
e. 属性填充
给 InstantiationAwareBeanPostProcessors.postProcessAfterInstantiation 最后一次机会,
通过属性注入改变 bean,它可以控制是否继续对bean进行属性填充。根据类型(type)或者 名称(name)注入依赖的bean;
InstantiationAwareBeanPostProcessor.postProcessPropertyValues 对需要依赖检查 的属性,在属性填充前,
进行后处理器 处理;将 PropertyValues [它缓存解析到的当前加载bean依赖的所有bean] 注入到 BeanWrapper[bean的包装器] 中。
f. 循环依赖检查
spring 解决依赖循环只对单例有效,prototype作用范围的bean, spring没有较好的解决办法,只能抛出异常。
g. 注册disposableBean
destory-method 定义的方法,对象销毁时调用。
Spring源码之bean的加载的更多相关文章
- 【Spring源码分析系列】加载Bean
/** * Create a new XmlBeanFactory with the given input stream, * which must be parsable using DOM. * ...
- Spring源码解析-配置文件的加载
spring是一个很有名的java开源框架,作为一名javaer还是有必要了解spring的设计原理和机制,beans.core.context作为spring的三个核心组件.而三个组件中最重要的就是 ...
- 五、spring源码阅读之ClassPathXmlApplicationContext加载beanFactory
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml&q ...
- Spring 系列教程之 bean 的加载
Spring 系列教程之 bean 的加载 经过前面的分析,我们终于结束了对 XML 配置文件的解析,接下来将会面临更大的挑战,就是对 bean 加载的探索.bean 加载的功能实现远比 bean 的 ...
- 从SpringBoot源码分析 配置文件的加载原理和优先级
本文从SpringBoot源码分析 配置文件的加载原理和配置文件的优先级 跟入源码之前,先提一个问题: SpringBoot 既可以加载指定目录下的配置文件获取配置项,也可以通过启动参数( ...
- 05 flask源码剖析之配置加载
05 Flask源码之:配置加载 目录 05 Flask源码之:配置加载 1.加载配置文件 2.app.config源码分析 3.from_object源码分析 4. 总结 1.加载配置文件 from ...
- Spring源码系列 — Bean生命周期
前言 上篇文章中介绍了Spring容器的扩展点,这个是在Bean的创建过程之前执行的逻辑.承接扩展点之后,就是Spring容器的另一个核心:Bean的生命周期过程.这个生命周期过程大致经历了一下的几个 ...
- Spring源码之Bean生命周期
https://www.jianshu.com/p/1dec08d290c1 https://www.cnblogs.com/zrtqsk/p/3735273.html 总结 将class文件加载成B ...
- Spring源码 21 Bean生命周期
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring mybatis源码篇章-Mybatis主文件加载
通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-SqlSessionFactory 前话 本文承接前文的内容继续往下扩展,通过Spring与Mybatis的 ...
随机推荐
- [转帖]Prometheus 监控之 Blackbox_exporter黑盒监测 [icmp、tcp、http(get\post)、dns、ssl证书过期时间]
Blackbox_exporter 主动监测主机与服务状态 Prometheus 官方提供的 exporter 之一,可以提供 http.dns.tcp.icmp 的监控数据采集 官方github: ...
- [转帖]Prometheus系列之Grafana 版本9.0.0 设置Email邮件报警实战
目录 1. 配置文件conf/defaults.ini修改 2. Grafana Web页面配置报警邮箱接收者 3. 创建Dashboard 4. 创建Alert的文件夹 5. 设置Notificat ...
- [转帖]MinIO系列7 - Minio性能压测
https://www.zhihu.com/people/keen-wang 前言 声明:此文为本人历史笔记的整理,文章实际撰写时间为2021年2月份,所以本中所使用的相关组件版本较老.此文是通过压力 ...
- [转帖]Kafka 与RocketMQ 落盘机制比较
https://www.jianshu.com/p/fd50befccfdd 引言 前几期的评测中,我们对比了Kafka和RocketMQ的吞吐量和稳定性,本期我们要引入一个新的评测标准--软件可靠性 ...
- [转帖]Native Memory Tracking 详解(4):使用 NMT 协助排查内存问题案例
https://www.modb.pro/db/557714 从前面几篇文章,我们了解了 NMT 的基础知识以及 NMT 追踪区域分析的相关内容,本篇文章将为大家介绍一下使用 NMT 协助排查内存问题 ...
- SAP Gateway Trace
最近在SAP PE项目上遇到一个需求要求记录所有的ODATA(含S4/CLOUD API)的报文. Below T-codes recording logging and tracing: /IWFN ...
- 【一文搞定】Linux、Mac、Windows安装Docker与配置教程!
目录 一.Windows 安装 1.1 安装与启用 Hyper-V 1.2 安装 WSL 1.3 Docker Desktop 官方下载 1.4 安装Docker Desktop 二.MacOS 安装 ...
- 即时通讯(IM)开源项目OpenIM每周迭代版本发布-音视频实时通话-v2.0.4
介绍 OpenIM每周五发布新版,包括新特性发布,bug修复,同时合并PR 由于2.0版本重构完毕,架构更清晰,代码更规范,先邀请各位参与OpenIM社区建设,包括技术开发,技术分享等,特性开发,性能 ...
- 推荐系统[四]:精排-详解排序算法LTR (Learning to Rank)_ poitwise, pairwise, listwise相关评价指标,超详细知识指南。
0.前言召回排序流程策略算法简介 推荐可分为以下四个流程,分别是召回.粗排.精排以及重排: 召回是源头,在某种意义上决定着整个推荐的天花板: 粗排是初筛,一般不会上复杂模型: 精排是整个推荐环节的重中 ...
- 常见的WCF面试问题
WCF和ASMX WebService的区别是什么? 最基本的区别在于,ASMX或者ASP.NET WebService是用来通过基于HTTP的SOAP来实现通讯.但WCF可以使用任意协议(HTTP, ...