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 執行個體建立時的調用堆棧。
觀察調用堆棧,是閱讀源碼的一個小技巧。可以快速的觀察到程式從開始到斷點處經過了哪些處理過程。![]()
【IoC-3】Spring 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)
如果本文對你有所幫助,歡迎點贊收藏!