干货分享之spring框架源码分析02-(对象创建or生命周期)
记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新。欢迎大家指正!
环境: spring5.X + idea
之前分析了Spring读取xml文件的所有信息封装成beanDefinition,并存到了beanDefinitionMap中以便我们后续使用。
传送门Spring源码分析01-(xml解析)
今天学习spring容器创建对象的整个过程,或者叫对象的生命周期
Spring创建对象的过程(基本数据beanDefinition)
// 第一步是完成对象创建所需要的基本数据也就是 beanDefinition
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
// 然后开始创建对象
User user = bf.getBean("user");
// 1. getBean() 进入 AbstractBeanFactory 中的 doGetBean 方法去做创建对象的具体步骤。
protected <T> T doGetBean(String name, ....................... ..) throws BeansException {
String beanName = this.transformedBeanName(name);
// 先去 DefaultSingletonBeanRegistry 中的 singletonObjects 获取对应的bean,
// 因为spring 默认 scope = singleton 单例bean不需要每次都创建
Object sharedInstance = this.getSingleton(beanName);
Object bean;
...........
// scope = Singleton
if(mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
// 开始去创建bean
return this.createBean(beanName, mbd, args);
}
......
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
// scope = Prototype
} else if(mbd.isPrototype()) {
var11 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
// 开始去创建bean
prototypeInstance = this.createBean(beanName, mbd, args);
}
...........
} else {
// 其他情况
...
}
}
// this.createBean(.....) 进入到 AbstractAutowireCapableBeanFactory 中的 createBean方法
protected Object createBean(String beanName...........) throws BeanCreationException {
try {
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if(this.logger.isDebugEnabled()) {
this.logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
..........
}
- Spring先实例化对象
dodoCreateBean 方法就是整个创建对象的核心方法
protected Object doCreateBean(String beanName............) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if(mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if(instanceWrapper == null) {
// 这里是 第一步创建对象
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
}
- 设置对象中的属性值
填充属性值// 还是刚才的 doCreateBean方法中
protected Object doCreateBean(String beanName............) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if(mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if(instanceWrapper == null) {
// 这里是 第一步创建对象
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object exposedObject = bean;
try {
// 这一步是填充属性
this.populateBean(beanName, mbd, instanceWrapper);
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
if(var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}
}
- 初始化对象
// 还是刚才的 doCreateBean方法中
protected Object doCreateBean(String beanName............) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if(mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if(instanceWrapper == null) {
// 这里是 第一步创建对象
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object exposedObject = bean;
try {
// 这一步是填充属性
this.populateBean(beanName, mbd, instanceWrapper);
// 这一步是初始化对象
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
if(var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}
}
- 销毁
DisposableBeanAdapter implements DisposableBean, Runnable, Serializable{
public void destroy() {
//销毁
}
}
最后
感谢您的阅读,有什么意见和问题欢迎评论区留言!书写不易!
觉得文章对你有帮助记得给我点个赞,欢迎大家关注和转发文章!
干货分享之spring框架源码分析02-(对象创建or生命周期)的更多相关文章
- 干货分享之Spring框架源码解析01-(xml配置解析)
记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新.欢迎大家指正! 环境: spring5.X + idea Spring 是一个工厂,是一个负责对象的创建和维护的工厂.它给我 ...
- Spring AMQP 源码分析 02 - CachingConnectionFactory
### 准备 ## 目标 了解 CachingConnectionFactory 在默认缓存模式下的工作原理 ## 前置知识 <Spring AMQP 源码分析 01 - Impatie ...
- 设计模式(五)——原型模式(加Spring框架源码分析)
原型模式 1 克隆羊问题 现在有一只羊 tom,姓名为: tom, 年龄为:1,颜色为:白色,请编写程序创建和 tom 羊 属性完全相同的 10 只羊. 2 传统方式解决克隆羊问题 1) 思路分析(图 ...
- Linux进程调度与源码分析(二)——进程生命周期与task_struct进程结构体
1.进程生命周期 Linux操作系统属于多任务操作系统,系统中的每个进程能够分时复用CPU时间片,通过有效的进程调度策略实现多任务并行执行.而进程在被CPU调度运行,等待CPU资源分配以及等待外部事件 ...
- Tomcat源码分析 | 一文详解生命周期机制Lifecycle
目录 什么是Lifecycle? Lifecycle方法 LifecycleBase 增加.删除和获取监听器 init() start() stop() destroy() 模板方法 总结 前言 To ...
- Spring IOC 源码分析
Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器.既然大家平时都要用到 Spring,怎么可以不好好了解 Spring 呢?阅读本文 ...
- Android Small插件化框架源码分析
Android Small插件化框架源码分析 目录 概述 Small如何使用 插件加载流程 待改进的地方 一.概述 Small是一个写得非常简洁的插件化框架,工程源码位置:https://github ...
- Spring AOP 源码分析 - 筛选合适的通知器
1.简介 从本篇文章开始,我将会对 Spring AOP 部分的源码进行分析.本文是 Spring AOP 源码分析系列文章的第二篇,本文主要分析 Spring AOP 是如何为目标 bean 筛选出 ...
- Spring AOP 源码分析系列文章导读
1. 简介 前一段时间,我学习了 Spring IOC 容器方面的源码,并写了数篇文章对此进行讲解.在写完 Spring IOC 容器源码分析系列文章中的最后一篇后,没敢懈怠,趁热打铁,花了3天时间阅 ...
随机推荐
- 用Python做了个奇奇怪怪的打篮球游戏
一.前言 准备编写一个篮球游戏,运动员带球跑,跳起投篮.在每帧图片中包括运动员和篮球,使用多帧图片,实现运动员运球跑动的效果. 运动员运球跑动作每帧图形的宽和高可能不同,例如,跨一大步,和两腿并拢,其 ...
- Jmeter系列(19)- 常用配置文件
JMeter.properties :跟Jmeter配置相关的配置信息都在这边,比如:Jmeter GUI页面的语言.日志级别设置等 User.properties:用户自定义相关的所有变量,会复写J ...
- python刷题第四周
本周有所收获的题目: 第一题: 第4章-17 水仙花数(20 分) (20 分) 水仙花数是指一个N位正整数(N≥3),它的每个位上的数字的N次幂之和等于它本身. 例如:153=1×1×1+5×5×5 ...
- FormData上传文件 带进度条
* jQuery ajax FormData 上传文件 template $.ajax({ url: url, type: 'POST', data: new FormData(form), dat ...
- JavaScript 获取html元素
1.通过ID获取: document.getElementById("idname"); 2.通过class.tagname获取: var wcyclass = document. ...
- Kronecker product
Kronecker product 的基本运算 结合律 \begin{equation} \mathrm{A} \otimes (\mathrm{B + C}) = \mathrm{A} \otime ...
- 小白自制Linux开发板 三. Linux内核与文件系统移植
上一篇完成了uboot的移植,但是想要愉快的在开发板上玩耍还需要移植Linux内核和文件系统. 1.Linux内核 事实上对于F1C100S/F1C200S,Linux官方源码已经对licheepi ...
- 移动端多个DIV简单拖拽功能
移动端多个DIV简单拖拽功能. 这个demo与之前写的一个例子差不了多少,只是这个多了一层遍历而已. <!DOCTYPE html> <html lang="en" ...
- 利用PATH环境变量 - 提升linux权限~👻
利用PATH提升linux权限 参考地址:https://www.hackingarticles.in/linux-privilege-escalation-using-path-variable/ ...
- 洛谷3809 SA模板 后缀数组学习笔记(复习)
其实SA这个东西很久之前就听过qwq 但是基本已经忘的差不多了 嘤嘤嘤 QWQ感觉自己不是很理解啊 所以写不出来那种博客 QWQ只能安利一些别人的博客了 小老板 真的是讲的非常好 不要在意名字 orz ...