Spring中bean的实例化过程
1.从缓存中。优先从一级缓存中拿,有则返回。 如果没有,则从二级缓存中获取,有则返回。 如果二级缓存中拿不到,则从三级缓存中拿,能拿到,则从三级缓存中删除,移到二级缓存。
如果三级缓存也没有,则返回null.
2. 如果是单例模式, 则走createBean 的流程,进行bean对象的实例化。
2.1 获取到该beanDefinition对应的字节码对象。
2.2 prepareMethodOverrides。 检查beanDefinition对象的每一个methodOverride的对象。如果该对象对应的同名的方法只有一个则设置为false, 默认设置为true.
2.3 调用doCreateBean 方法,进行具体的实例化过程。
3.
3.1 如果是单例的,则从bean工厂的实例缓存中获取bean对象。
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
3.2 如果获取到的为空, 则进行bean对象的实例化创建。调用createBeanInstance
if (instanceWrapper == null) {
//创建实例,,重点看,重要程度:5
instanceWrapper = createBeanInstance(beanName, mbd, args);
} 3.3如果有FactoryMethodName属性,则通过factorymethod 方法进行对象的实例化。
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
} 3.4 否则,寻找当前正在实例化的bean中有@Autowired注解的构造函数
// 调用SmartInstantiationAwareBeanPostProcessor类型的beanpostProcess.determineCandidateConstructors 获取有autowired和value注解的构造器。
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); 3.5 //如果ctors不为空,就说明构造函数上有@Autowired注解, 则通过构造函数进行初始化。
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//如果ctors不为空,就说明构造函数上有@Autowired注解
return autowireConstructor(beanName, mbd, ctors, args);
} 3.6 如果首选的构造器不为空, 则使用首选的构造器进行实例化,以及进行以来注入
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
} 3.7 否则调用无参构造函数进行bean的实例化。
//无参构造函数的实例化,大部分的实例是采用的无参构造函数的方式实例化,并包装成一个BeanWrapper 对象进行返回。
return instantiateBean(beanName, mbd); 4. 调用applyMergedBeanDefinitionPostProcessors。主要是对实现了MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法调用。
主要的实现类有: 4.1 AutowiredAnnotationBeanPostProcessor。在postProcessMergedBeanDefinition方法中实现对Autowired,Value注解的注解信息收集,封装到externallyManagedConfigMembers。
4.2 CommonAnnotationBeanPostProcessor。 在postProcessMergedBeanDefinition方法中实现对@PostConstrutor 和 @ PreDestory ,@Resource 注解的信息收集,封装到externallyManagedConfigMembers。
5. 检查是否允许循环依赖,以及是否是单例模式。满足条件的话,从二级缓存中移除,并且添加到三级缓存中。
6.进行属性的注入,调用populateBean 方法。
6.1 根据注入的模式,进行对应属性的字段,filed ,以及method依赖的解析。获取其依赖的对象的值。
6.2 调用实现了InstantiationAwareBeanPostProcessor接口的postProcessProperties 方法,对有autowired,value,resource 注解的属性实现属性值的注入。
在AutowiredAnnotationBeanPostProcessor中实现对autowired,value 属性的注入。
在CommonAnnotationBeanPostProcessor中实现对resource 属性的注入。
6.3 调用applyPropertyValues 方法,实现对<property/> 标签的属性值的解析。 7.调用bean的initializeBean方法,完成bean 实例化过程的后续操作。 7.1 调用invokeAwareMethods 方法。根据是否实现了 一系列的aware 接口,调用其对应的方法
7.2 调用BeanPostProcessor接口的postProcessBeforeInitialization方法。进行bean初始化的前期方法调用。对 initmethod,,afterpeoperties, postcontructor 方法调用。 1.InitDestroyAnnotationBeanPostProcessor中实现对@PostContrustor注解标识的方法进行调用
2.调用实现了InitializingBean 接口的afterpropertiesSet 方法。
3.调用指定了init-method属性的方法。
7.3 调用applyBeanPostProcessorsAfterInitialization方法,实现对BeanPostProcessor的postProcessAfterInitialization的方法的调用(TODO 这一个涉及到AOP的实现。后续完善。)
8.调用 registerDisposableBeanIfNecessary 方法。实现spring容器销毁时,bean 对象销毁是的操作注册。
Spring中bean的实例化过程的更多相关文章
- Spring中Bean的实例化
Spring中Bean的实例化 在介绍Bean的三种实例化的方式之前,我们首先需要介绍一下什么是Bean,以及Bean的配置方式. 如果 ...
- Spring中Bean的实例化与DI的过程
引言 前文我们介绍了关于如何学习Spring的源码以及解析了spring中加载配置文件注册Beandefinition的过程.今天我们继续学习DI的过程. 创建实例和DI过程 IOC和DI都是对spr ...
- 指定spring中bean启动的顺序
参考链接: https://www.jb51.net/article/125846.htm 使用DependsOn Spring 中的 DependsOn 注解可以保证被依赖的bean先于当前bean ...
- spring中bean实例化时机以及整个运转方式
接上一篇文章,一般在servlet获取到请求之后 在service方法中就可以完成所有的请求处理以及返回,但是我们会采用更高级的MVC框架来做.也就是说所有的MVC框架入口就是serlvet中的ser ...
- Spring 源码学习 - 单例bean的实例化过程
本文作者:geek,一个聪明好学的同事 1. 简介 开发中我们常用@Commpont,@Service,@Resource等注解或者配置xml去声明一个类,使其成为spring容器中的bean,以下我 ...
- 一次性讲清楚spring中bean的生命周期之三:bean是如何实例化的
在前面的两篇博文<一次性讲清楚spring中bean的生命周期之一:getSingleton方法>和<一次性讲清楚spring中bean的生命周期之二:FactoryBean的前世今 ...
- 简:Spring中Bean的生命周期及代码示例
(重要:spring bean的生命周期. spring的bean周期,装配.看过spring 源码吗?(把容器启动过程说了一遍,xml解析,bean装载,bean缓存等)) 完整的生命周期概述(牢记 ...
- 通过BeanPostProcessor理解Spring中Bean的生命周期
通过BeanPostProcessor理解Spring中Bean的生命周期及AOP原理 Spring源码解析(十一)Spring扩展接口InstantiationAwareBeanPostProces ...
- 深究Spring中Bean的生命周期
前言 这其实是一道面试题,是我在面试百度的时候被问到的,当时没有答出来(因为自己真的很菜),后来在网上寻找答案,看到也是一头雾水,直到看到了<Spring in action>这本书,书上 ...
随机推荐
- H3C IP路由表摘要信息
- 1625 - Color Length——[动态规划]
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- Vue基础练习之Todo List
<body> <div id = "app"> <input type="text" v-model="inputVal ...
- 1134 最长上升子序列 (序列型 DP)
思路: 由于一般的动态规划时间复杂度是O(n^2)(哈哈哈哈 第一次用的就是这个!)用在这里由于n最大为50000 所以会超时 到这里我们可以用一个数组来动态维护这个最长上升的子序列,将你要输入的子序 ...
- <QluOJ2018NewCode>计算几何(寄蒜几盒)
题目描述 现在有一个圆圈,圆圈上有若干个点,请判断能否在若干个点中选择三个点两两相连组成一个等边三角形? 这若干个点在圆圈上按顺时针顺序分布. 如果可以的话输出"Yes"(不含引号 ...
- Kubernetes从私有镜像仓库中拉取镜像
当我们尝试从私有仓库中拉取镜像时,可能会收到这样提示:requested access to the resource is denied Error response from daemon: pu ...
- javeweb_学生信息添加系统
在text.jsp中画出界面,以及设置提交选项的限制 <%@ page language="java" contentType="text/html; charse ...
- Kubernetes基本概念和术语之《Pod》
Pod是Kubernetes的最重要也最基本的概念.我们看到每个Pod都有一个特殊的被称为“根容器”的Pause容器对应的镜像属于Kubernetes平台的一部分.除了Pause容器,每个Pod还包含 ...
- mysql锁及四种事务隔离级别笔记
前言 数据库是一个共享资源,为了充分利用数据库资源,发挥数据 库共享资源的特点,应该允许多个用户并行地存取数据库.但这样就会产生多个用户程序并 发存取同一数据的情况,为了避免破坏一致性,所以必须提供并 ...
- js对当前时间进行处理
//1.JS获取两个日期之间相差的天数 function getDaysBetween(dateString1, dateString2) { var startDate = Date.parse(d ...