¶一次Spring Bean 对象debug过程
¶概述
用了Spring 这么久,除了觉得它对于web开发十分便利之外,并没有太多地了解它内部的一些实现过程。之前听人提起过,debug的方式可以带你一步一步跟着框架的执行思路了解它的内部机制,因此尝试了一下;( 懒得分开写,文字很多,嫌麻烦可以直接翻到最后的流程图 )
标准的SpringBoot项目,断点的代码比较简单:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class UserService { //断点处
private UserMapper userMapper;
public int addUser(User user){
return userMapper.insert(user);
}
public User getUser(Integer userId){
return userMapper.selectByPrimaryKey(userId);
}
public User getUserByName(String userName){
return userMapper.getUserByName(userName);
}
}断点打在第三行,类加载的时候
¶过程
¶零散的执行流程:
最先执行到的Spring 相关联的代码是
BeanUtils
的instantiateClass(Constructor<T> ctor, Object... args)
,根据形参的构造方法和对象参数,返回一个当前对象的实例,值得注意的是它会捕获四个异常:- 当试图实例化一个抽象类时,捕获
InstantiationException
异常 - 当构造函数是私有修饰时,捕获
IllegalAccessException
异常,这在反射中也能见到 - 当构造函数参数不合法时,捕获
IllegalArgumentException
异常 - 当反射调用异常时,捕获
InvocationTargetException
,这个异常是一个受检查异常,通常由被引用的方法或者构造函数抛出
- 当试图实例化一个抽象类时,捕获
一路 StepOver 就到了
SimpleInstantiationStrategy
类的instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)
方法,这个方法的参数中有两个是比较显眼的String beanName 和 BeanFactory owner
,分别是实例化的 bean 的名字和所属的 beanFactory 实例,类名是 UserService,@Service 注解中也没有声明任何beanName相关的信息,所以看到的信息如下:RootBeanDefinition bd
对象里面可以看到关于当前这个bean 的一些信息 ,值得一看的是 :scope = singleton , 说明这是个单例的bean
beanClass =class producer.service.UserService , 这个bean是 UserService 类的实例
lazyInit = null , 是否延迟初始化,这里是 null ,表示不会延迟初始化
awtowireMode = 0,简单翻译成注入模式,这个属性的定义并不在
RootBeanDefinition
里面,而是它从父类AbstractBeanDefinition
继承过来的,取值共有四种,分别对应AutowireCapableBeanFactory
的四个属性:- int AUTOWIRE_NO = 0 , 不指定具体的bean注入方式,表示继续使用 BeanFactoryAware 和 注解驱动的注入
- int AUTOWIRE_BY_NAME = 1,通过 beanName 注入
- **int AUTOWIRE_BY_TYPE = 2 **,通过bean类型注入
- int AUTOWIRE_CONSTRUCTOR = 3 ,构造方式注入
- int AUTOWIRE_AUTODETECT = 4,自行检查选择合适的注入方式,不过从 Spring 3.0 开始标记为废弃,推荐使用注解驱动的注入方式代替混合注入方法
beanName = "userService "
,因为没有指定 beanName,所以使用类构造的方法名作为beanNameower
,是DefaultListableBeanFactory
的实例,这说明,注解驱动模式下,使用的BeanFactory 实现是 DefaultListableBeanFactory 类;对象持有一个beanDefinitionMap
属性,里面放了啥呢?所有已经获取到的BeanDetinition
对象信息,如下图所示:
咱们来捋一捋 :
DefaultListableBeanFactory
是什么 ? Bean 容器对吧,它继承了AbstractAutowireCapableBeanFactory
抽象类,实现了ConfigurableListableBeanFactory
接口;beanDefinitionMap
里面放了啥? 已经获取到的BeanDefinition
对象的信息对吧;了解过spring bean 创建的朋友肯定知道,spring的bean对象并不是立刻创建的,也就是createBean
这个动作只会发生在真正需要bean
对象的时候,在这之前所有的Bean对象信息都保存在 bean 容器的beanDefinitionMap
中既然它是个map,那肯定有key对吧,有哪些 key 呢?瞄一眼:
没有瞎的朋友们肯定看明白了,这里的key有两种 ; 实例对象的名称和类型。记得前面的 bean注入模式中有name注入,type注入;这意味只需要提供 beanName 或者 bean的类信息就可以获得对应的
BeanDefinition
信息并且以此来创建Bean实例
到这里大致看明白了一些bean注入模式实现的信息,继续往下;
下一步跳转到
AbstractAutowireCapableBeanFactory
的instantiateBean
方法参数是String beanName,RootBeanDefinition bd
,根据beanName使用默认构造创建bean实例;这里开始就是创建bean对象相关的东西了,这里返回了一个beanInstance ,从哪里来的呢 ? 就是从上面的过程中返回过来的 :1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements
AutowireCapableBeanFactory{
......
protected BeanWapper instantiateBean(final String beanName,final RootBeanDrfinition mbd){
......
Object beanInstance = getInstantiationStrategy().instantiate();
......
}
}
//上面这个调用指向了
public class SimpleInstantiationStrategy implements InstantiationStrategy{
......
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName,
BeanFactory owner){
......
return BeanUtils.instantiateClass(constructorToUse);
......
}
......
}
//很好,这个翻译过来叫做 `简单初始化策略`的类,调用了 BeanUtils.instantiateClass(contructorToUse)方法,参数是要创建的对象的构造方法
public abstract class BeanUtils{
......
public static <T> T instantiateClass(Constructor<T> ctor, Object... args){
......
return (KotlinDetector.isKotlinReflectPresent()
&& KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
......
}
......
}
//这里还进行了是否属于Ktolin反射对象的判断,如果不是则最后调用 Constructor 类的newInstance(args)方法进行实例化并返回实例化了 beanInstance 之后,开始创建
BeanWapper
对象,我看了一眼此时的 userService 对象,发现它是这样的:userService 内部是注入了
UserMapper userMapper;
对象的,但是这时候还是个null,也就是这个bean对象的属性注入并没有完成,先接着看BeanWapper。BeanWrapper
是个啥?文档的注释是:1
2
3
4>Provides operations to analyze and manipulate standard JavaBeans:
>the ability to get and set property values (individually or in bulk),
>get property descriptors, and query the readability/writability of properties.
>提供基本Bean对象的分析和管理能力,包括设置属性值,获取属性修饰符,读写权限等。wapper直接翻译过来是包装的意思,这个 BeanWapper 可以理解成 Bean 实例的包装类,拥有bean实例的属性信息并且可以进行设置等。
现在debug进行到的方法是
doCreateBean
方法,贴一下代码帮助理解:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd,
final @Nullable Object[] args){
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//如果当前bean定义信息表明是个单例的bean对象,会从FactoryBean name 和 BeanWapper
//的缓存集合中移除当前bean对象
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//这里就是前面返回的beanWapper对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 用来获取beanWapper对象包装的bean对象
final Object bean = instanceWrapper.getWrappedInstance();
//获取Bean实例的类型
/*(这里先记一下:不明白为什么不直接把bean对象拿来用?)*/
Class<?> beanType = instanceWrapper.getWrappedClass();
......
}到这里已经是获取到了 bean 对象本身和 bean 对象的类,虽然有点疑问为什么不直接把bean对象信息拿出来用而是加了个BeanWapper。
下面的东西就比较令人在意,提到了循环引用:
先说下循环引用的概念:假设A依赖B,B依赖C,C依赖A,那么在对A,B,C三个Bean进行实例化的时候,会发现要是实例化A需要完成属性B的实例化,而要实例化B,需要完成属性C的实例化,而C则需要属性A的实例化,一个循环就形成了,谁的实例化条件都无法满足。
1
2
3
4
5
6
7
8
9
10
11// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}这里的
earlySingletonExposure
是通过三个条件判断的:是否单例bean,是否允许循环引用,当前bean对象是否正在创建。满足这三个条件的情况下,会做两件事:提前获取bean对象的引用,将这个引用添加到指定的单例工厂中。addSingletonFactory()
方法是DefaultSingletonBeanRegistry
类的方法,会根据beanName判断指定的bean对象是否存在于单例的bean集合中,如果不存在,通过this.singletonFactories.put(beanName, singletonFactory);
将bean对象和参数的单例工厂绑定起来,并将beanName添加到已注册单例集合中。调用的方法是这两个:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
* Obtain a reference for early access to the specified bean,
* typically for the purpose of resolving a circular reference.
* @param beanName the name of the bean (for error handling purposes)
* @param mbd the merged bean definition for the bean
* @param bean the raw bean instance
* @return the object to expose as bean reference
*/
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
// 判断了当前的RootBeanDefinition 对象是否是应用自身创建的bean对象
// 判断当前bean 是否添加了前置初始化回调方法,InstantiationAwareBeanPostProcessor 接口
// 提供了bean创建之前的回调方法和bean初始化之后但是属性显示设置之前或自动注入发生之前的回调
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
//这一步没看大明白,因为当bp 是 SmartInstantiationAwareBeanPostProcessor的实例时
//会直接返回参数的bean对象,
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
/**
* Add the given singleton factory for building the specified singleton
* if necessary.
* <p>To be called for eager registration of singletons, e.g. to be able to
* resolve circular references.
* @param beanName the name of the bean
* @param singletonFactory the factory for the singleton object
*/
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}方法注释的意思大致是:为了在必要时候创建指定的bean对象而添加给定的单例工厂对象,有点拗口。这里提到了四个缓存集合:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15/** Cache of singleton objects: bean name to bean instance. */
// 单例bean的缓存,beanName = bean 的映射
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name to ObjectFactory. */
// 单例工厂的缓存, beanName = ObjectFactiry 对象的映射
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name to bean instance. */
// 提前创建的 bean对象的缓存集合, beanName 和 bean实例的映射
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/** Set of registered singletons, containing the bean names in registration order. */
// 根据bean的注册顺序缓存的bean集合
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);顺序是:先查找单例对象缓存集合是否缓存了当前bean对象 ,如果没有缓存,将当前的beanName 和单例工厂对象缓存起来,从 earlySingletonObjects 缓存中移除当前 beanName 对应的对象,将 beanName 对应的实例作为已注册bean缓存起来。这里是个考点,当前正在创建的允许循环引用的单例bean,会缓存到已注册bean缓存集合中。
但是到这一步为止,
userService
的bean对象本身还没有创建完成,它依赖的beanuserMapper
并没有被注入,接下来会调用populateBean(beanName, mbd, instanceWrapper);
方法,根据 beanDefinition 中的bean的定义填充bean属性,这里可以延申一下思维:bean的属性也是个bean的话该怎么办?当然是原谅…哦不是,当然是先实例化它了~1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58......
Object exposedObject = bean;
try {
//根据beanDefinition 的bean信息进行bean的属性填充,
//不过我debug看到 RootBeanDefinition mbd 的propertiesValues 的集合为空,没有需要填充的属性
populateBean(beanName, mbd, instanceWrapper);
//这里就是初始化bean了,主要是调用初始化方法和一些前置和后置初始化回调方法,
exposedObject = initializeBean(beanName, exposedObject, mbd);
......
//如果是允许提前初始化的bean,就获取bean的引用
if (earlySingletonExposure) {
//从缓存中查找bean的引用,
Object earlySingletonReference = getSingleton(beanName, false);
......
// 判断是否存在依赖当前bean的bean对象,因为如果存在,则说明当前bean已经被创建过了,
// 会抛出一个 BeanCurrentlyInCreationRxception 异常
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
......
}
}
......
//注册bean
try {
//将参数的bean 对象加入到bean容器的一次性bean集合中
//会注册bean的 DisposableBean 接口(当destory方法需要释放资源的时候实现此接口)
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
......
}
......
//上面调用的 initializeBean 方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
......
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//应用前置初始化回调,bean如果存在属性的情况下,已经由 populateBean()填充完毕
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//反射初始化方法
//会判断是否实现了InitializingBeannit 接口,决定是否调用 afterPropertiesSet 方法
//没有实现此接口的情况下,会反射去查找指定的初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}到bean注册完成那一步,整个
doCreateBean
方法就执行完成了,不过上面的过程理解整体看起来比较零散,现在尝试把它们的流程整合一下:1
2
3
4
5
6
7
8
9
10
doCreateBean(String beanName,RootBeanDefinition mbd,Object[] args)
--> 判断当前bean定义信息是否是单例
-->如果当前创建的是单例bean对象,则从 FactoryBean 和 BeanWapper 的映射中获取bean引用
--> 前面获取到的bean如果是空,则需要进行BeanWapper 对象的创建,注意这里还只是BeanWapper 对象
--> 然后加锁,获取当前bean对象的其他BeanDefinition信息,进行合并
--> 接下来就是处理循环依赖的场景了,首先提前获取了bean的引用,在已注册的bean缓存中查找指定的bean对象,判断是否是已经实例化的bean对象,如果不是;则将beanName和beanFactory实例缓存起来
--> 然后就是开始初始化bean对象,进行bean对象的属性填充和应用初始化以及初始化回调方法
--> 将完成了属性填充之后开始注册bean对象,同时注册bean的destory方法,在应用停止的时候调用
--> 返回bean对象doCreateBean
的过程看起来是这样的,但是我还是没有明白哪里体现出来了处理循环引用的问题,尝试debug向下走,一直返回到AbstractBeanFactory
的doGetBean(String name,SClass<T> requiredType,Object[] args,boolean typeCheckOnly)
方法,这里最开始就会尝试从缓存中查找当前需要创建的bean对象:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38protected <T> T doGetBean(......){
......
//从缓存中查找当前bean对象
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
......
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
......
}
//最终指向的 getSingleton(beanName,true)方法
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 从第一层缓存中查找beanName对应的bean对象
Object singletonObject = this.singletonObjects.get(beanName);
//如果bean不存在且正在创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//锁住第一层缓存,防止并发写入
synchronized (this.singletonObjects) {
//从第二层缓存中查找指定的bean
singletonObject = this.earlySingletonObjects.get(beanName);
//如果仍然为空且允许提前获取bean的引用
if (singletonObject == null && allowEarlyReference) {
//尝试从第三层缓存中查找beanName 对应的 beanFactory 对象
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}如果当前需要的bean正在创建中,且缓存中不存在,则返回空,说明bean没有被创建过;如果获取到了非空的bean对象,但是对象正在创建中,那说明由于处理循环引用,bean对象还没有实例化完成;获取到空的bean对象时也会先进行bean对象是否正在创建的判断,为了避免对bean对象的重复创建。
接下来就是查找BeanDefinition信息,如果存在BeanDefinition信息那么也可以根据这些信息构造出bean对象来:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
//可能出现自定义beanName找不到bean对象的情况,尝试将beanName解析成规范化的名称重新调用doGetBean
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}当通过类型,参数,规范化的beanName等任意一种方式获取到bean对象之后都会直接返回bean对象;
如果也不存在BeanDefinition信息的话,只能通过beanName等参数去创建Bean,会先将当前bean依赖的bean对象都初始化完成,再来创建当前bean对象:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
//如果它们之间还存在反向的依赖关系,则是循环依赖
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//注册当前beanName依赖的depBean对象
registerDependentBean(dep, beanName);
try {
//检查是否成功初始化了依赖的depBean对象
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
¶重新梳理完整的过程:
这里要先确定一些东西,上面零散的debug过程,是从
BeanUtils
类开始的,但这明显是个底层的工具类方法,从这里开始是看不明白的,debug的过程是从代码执行的最深处向上返回,所以上面的执行过程应该反过来看好理解一点起点
AbstractBeanFactory.doGetBean(String name,Class<T> requiredType,Object[] args,boolean typeCheckOnly)
:返回指定bean的共享或独立的实例对象
执行过程:
final String beanName = transformedBeanName(name);
: 当存在 bean 的别名与已经实例化的bean name 匹配的时候,返回规范化的beanNameObject sharedInstance = getSingleton(beanName);
: 调用DefaultSingletonBeanRegistry.getSingleton(String beanName,boolean allowEarlyReference)
依次从单例对象缓存,单例工厂对象缓存,提前引用单例对象缓存中查找指定的bean,允许提前缓存的bean对象,通常是为了识别以及处理循环依赖的问题;我这里的userService 是新创建的bean对象,所以没有被任何一个地方缓存,因此会继续向下;会获取到RootBeanDefinition 对象,调用它的
getDependsOn()
方法,获取当前bean
所依赖的bean对象,确保它们在当前bean初始化之前已经被初始化(如果还是按照以前由对象自身管理自身的依赖对象,那么这一步就变成主动去调用所有对象的初始化方法了,依赖的对象一旦多起来,就会看的头皮发麻)。在查找存在依赖bean对象之后,会再反过来确认一遍bean之间的依赖关系,如果反向依赖关系也存在,那说明他们之间形成了环形依赖,会直接抛出异常,说明这种情况是它处理不了的循环依赖。因为根据接下来的步骤:
registerDependentBean(dep,beanName)和getBean(dep)
,注册依赖对象和bean对象,然后获取bean对象,getBean()
方法又会调用当前的doGetBean()
,因此如果当前bean和依赖bean还存在反向依赖,就会陷入创建bean的死循环了,所以直接抛出异常是对的。随后是进行bean类型的判断,
singleton,prototype和其他
,根据不同的bean类型通过不同的流程创建bean对象;单例bean对象还是会调用DefaultSingletonBeanRegistry.getSingletoon()
方法从换从中查找bean对象,这里会先进行bean的创建,再从缓存中获取bean对象:1
2
3
4
5
6
7
8
9
10
11
12
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
...
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}getSingleton的第二个参数是实现ObjectFactory的接口,调用的
createBean()
方法创建bean,最终调用的是AbstractAutowireCapableBeanFactory.createBean()
方法,而这个方法我们之前其实提到了,因为它做了一些准备工作之后,就会调用doCreateBean()
方法去创建bean对象了所以整个过程也就串起来了: (流程图: https://www.processon.com/view/link/5f16ec21f346fb5cdc98e09a)
整个的
getBean()
方法调用过程大概就是这样子了
¶小结:
- 在ApplicationContext 中,会一次性创建好所有需要的bean对象,从调用
getBean()
方法开始 - 存在着几层bean对象的缓存,分别存放着不同类型的bean对象:单例bean,beanName-benFactory 映射,createdBean 对象等,除了第一次会执行bean的创建过程,之后每次都会尝试从这些缓存中获取单例bean
- 对于单例和多实例的bean对象,创建过程是有很大区别的,多实例bean对象创建后不会缓存,会有明显的前后置方法调用
- //TODO