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>这本书,书上 ...
随机推荐
- P1036 最大公约数
题目描述 给你两个正整数A和B,求它们的最大公约数. 输入格式 两个正整数 \(A,B(1 \le A,B \le 10^9)\) . 输出格式 一个整数,表示A和B的最大公约数. 样例输入 6 8 ...
- dotnet 使用 GC.GetAllocatedBytesForCurrentThread 获取当前线程分配过的内存大小
在 dotnet framework 4.8 的时候支持调用 GC.GetAllocatedBytesForCurrentThread 获取当前线程分配过的内存大小 创建一个简单的控制台程序,在调用 ...
- H3C 端口隔离基本配置
- 2019-8-31-C#-如何写-DEBUG-输出
title author date CreateTime categories C# 如何写 DEBUG 输出 lindexi 2019-08-31 16:55:58 +0800 2018-2-13 ...
- Linux 内核取消 urb
为停止一个已经提交给 USB 核心的 urb, 函数 usb_kill_urb 或者 usb_unlink_urb 应 当被调用: int usb_kill_urb(struct urb *urb); ...
- Crazy Binary String<Map法>
#include<cstdio> #include<iostream> #include<map> using namespace std; map<int, ...
- 【转】Elasticsearch学习笔记
一.常用术语 索引(Index).类型(Type).文档(Document) 索引Index是含有相同属性的文档集合.索引在ES中是通过一个名字来识别的,且必须是英文字母小写,且不含中划线(-):可类 ...
- CachedRowSet 接口
Sun Microsystems 提供的 CachedRowSet 接口的参考实现是一个标准实现.开发人员可以按原样使用此实现.可以扩展它,也可以选择自己编写此接口的实现. CachedRowSet ...
- STM32与STM8操作寄存器的区别
在STM8中,由于STM8寄存器较少,在头文件中定义寄存器的时候不用采取任何形式的封装,所以操作寄存器的时候直接可以用如下方式处理:PB_DDR |=0x20; 但是在STM32中,由于其寄存器实在太 ...
- Raid相关操作与注意事项记录
Raid相关操作与注意事项 Raid5 SATA盘组成的Raid5,在保护数据的前提下达到高性能: RAID要有BBU Current Cache Policy采用WriteBack,No Write ...