bean 的创建过程
- 前言
- 正文
- 补充:bean 创建的完整过程
- 小结
系列博文:
【IoC-0】SpringIoC引入
【IoC-1】IoC之控制反转引入
【IoC-2】IoC之BeanDefinition扫描注册
【IoC-3】Spring bean 的创建过程
【IoC-4】IoC之依赖注入原理
相关阅读:
@Resource与@Autowired的区别
前言
Spring 提供了"控制反转"的能力,也就是将 bean 的创建交由 Spring 去统一处理。
前文分析了要实现"控制反转"的功能,Spring 需要解决的问题是:
- BeanDefinition 的扫描和注册
- 根据 BeanDefinition 来创建 bean 的实例
可以说"BeanDefinition 的扫描和注册"只是前戏,bean 实例的创建才是主菜。
上一篇已经分析了 BeanDefinition 的扫描和注册,这里我们主要再分析一下 bean 实例的创建过程。
正文
一个普通的单例 bean,如果没有特殊的指定 FactoryMethod 或者 constructor 的话,就会使用默认的构造函数来创建 bean 的实例。
那么,我们可以为一个普通的单例 bean 添加一个默认的构造函数,然后在上面打上断点,来观察 bean 实例创建时的调用堆栈。
观察调用堆栈,是阅读源码的一个小技巧。可以快速的观察到程序从开始到断点处经过了哪些处理过程。
从调用堆栈中,可以看到,bean 实例的创建是在执行
AbstractApplicationContext#finishBeanFactoryInitialization()
的时候,调用
AbstractBeanFactory#getBean()
触发的。
最终会调用
AbstractAutowireCapableBeanFactory#createBeanInstance()
:
/**
* 通过一定的实例化策略,为指定的 bean 创建一个新的实例。
* 实例化策略为: FactoryMethod --> constructor autowiring(构造注入) --> simple instantiation(调用默认构造函数)
* Create a new instance for the specified bean, using an appropriate instantiation strategy: factory method, constructor autowiring, or simple instantiation.
*/
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 1. 通过指定的 FactoryMethod 来创建 bean 的实例
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
} else {
return instantiateBean(beanName, mbd);
}
}
// 2. 构造注入
// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 3. 使用无参构造函数来创建 bean 的实例。(即默认的构造函数)
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
补充:bean 创建的完整过程
createBeanInstance()
方法只是将 bean 的实例创建出来了,它还不是一个完整的 bean,因为 bean 里面依赖的属性还没有填充值。
AbstractAutowireCapableBeanFactory.doCreateBean()
的源码可以看到 bean 完整的创建过程:
小结
bean 实例的创建是在执行
AbstractApplicationContext#finishBeanFactoryInitialization()
的时候,调用
AbstractBeanFactory#getBean()
触发的。
最终是由
AbstractAutowireCapableBeanFactory#createBeanInstance()
方法来完成 bean 实例的创建的。
bean 实例的创建策略为(优先级级从前往后):
- 通过指定的 FactoryMethod 来创建
- 构造注入的方式(通过指定的构造函数)
- 通过默认的构造函数来创建
创建一个完整的 bean 分三个阶段:
-
AbstractAutowireCapableBeanFactory#createBeanInstance()
创建 bean 的实例
-
AbstractAutowireCapableBeanFactory#populateBean()
填充 bean 的依赖
-
AbstractAutowireCapableBeanFactory#initializeBean()
初始化 bean。
对 bean 的实例执行一些初始化方法:
awareMethods --> BeanPostProcessor --> initMethod(InitializingBean#afterPropertiesSet、指定的 initMethod)
如果本文对你有所帮助,欢迎点赞收藏!