在經歷了前面
BeanDefinition
定義和BeanPostProcessor
的準備工作完成之後,終於到了千呼萬喚始出來的bean
實例初始化了,也就是平時想用哪個類對應的實例直接從BeanFactory
要的對象時怎麼被創建出來的?由於這塊邏輯比較複雜,還涉及到"循環依賴"等等一系列問題,所以我會在接下來利用兩三篇文章來逐一說明。你們準備好一次搞定bean
實例初始化的流程了嗎?關於測試用例我們還是沿用UserService
。
說明一下,關於以下幾個方法,不是我們關注的重點,暫時先不討論,後面有時間我們在來介紹
initMessageSource()
:初始化國際化相關initApplicationEventMulticaster()
:初始化事件分發器onRefresh()
:初始化特殊的bean實例,無任何實現,預留出來的擴展點registerListeners()
:註冊監聽器
關於
BeanDefinition
的幾點提前說明
GenericBeanDefinition
:配置爲xml文件被解析爲這個BeanDefinition
定義ScannedGenericBeanDefinition
:由註解聲明的被解析成這個BeanDefinition
在bean實例化開始我們會遇到一個叫
mergedBeanDefinition
的bean定義,由於BeanDefinition
會存在如下情況:
BeanDefinition
存在父BeanDefinition
BeanDefinition
不存在父BeanDefinition
且本身是一個RootBeanDefinition
BeanDefinition
不是一個RootBeanDefinition
,而是一個自定義的BeanDefinition
所以在bean實例化開始把這些情況統一命名爲mergedBeanDefinition。
看看
finishBeanFactoryInitialization()
的具體實現。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// Step1:初始化當前上下文的轉換器
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// Step2:如果BeanFactory沒有內嵌值解析器,則添加一個默認的值解析器,這個解析器的作用是將註解裏面配的類似 ${} 替換成真正的值
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// Step3:初始化LoadTimeWeaverAware bean實例
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
// Step4:凍結BeanDefinition定義,因爲之後就是開始創建BeanDefinition對應的實例了
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// Step5:重點,實例化所有剩餘的非懶加載的單例Bean實例
beanFactory.preInstantiateSingletons();
}
來看下
beanFactory.preInstantiateSingletons()
的具體實現。
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// Step1:遍歷當前BeanFactory裏面的所有beanName
for (String beanName : beanNames) {
// Step1.1:根據beanName獲取對應的MergedBeanDefinition定義。
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// Step1.2:bd不是抽象的 && bd是單例的 && bd是非懶加載的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// Step1.2.1:根據當前beanName判斷對應的bean實例是否是一個FactoryBean。
if (isFactoryBean(beanName)) {
// Step1.2.1.1:帶上前綴獲取FactoryBean
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
// Step1.2.1.2:獲取到的bean是一個FactoryBean
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
// Step1.2.1.3:需要提前加載,根據beanName獲取對應的bean實例並將其註冊到BeanFactory裏面。
if (isEagerInit) {
getBean(beanName);
}
}
}
//1.2.2:非FactoryBean,則直接獲取對應的bean實例並將其註冊到BeanFactory裏面。
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// Step2:遍歷beanName獲取對應的bean實例。
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
// Step2.1:如果當前實例實現了SmartInitializingSingleton,則可以調用其實現的afterSingletonsInstantiated方法,可以在這個方法中做一些事情。
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
// Step2.1.1:是否需要安全檢測
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
基於以上的實現,我們先來看看如果根據
beanName
獲取到對應的MergedBeanDefinition
定義的。
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
// Step1:存MergedBeanDefinitions緩存獲取對應的BeanDefinition定義,快速返回BeanDefinition定義,這種類似的緩存在Sprin後面的源碼也會大量用到,我們在文末總結一下今天見到的本地緩存
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
// Step2:首先根據beanName獲取到對應的BeanDefinition定義,然後在根據BeanDefinition和beanName獲取到RootBeanDefinition。
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
// Step1:從beanDefinitionMap獲取對應的BeanDefinition,這裏存放的就是我們在 obtainFreshBeanFactory() 方法裏面創建出來的BeanDefinition定義,理論上這裏肯定可以獲取得到對應的BeanDefinition,如果取不到就拋出異常。
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
if (bd == null) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("No bean named '" + beanName + "' found in " + this);
}
throw new NoSuchBeanDefinitionException(beanName);
}
return bd;
}
根據
beanName
和BeanDefinition
獲取對應的RootBeanDefinition
定義
// 拿到了beanName和對應的BeanDefinition定義,我們來看看是怎麼獲取到對應的RootBeanDefinition定義的。
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
// Check with full lock now in order to enforce the same merged instance.
// Step1:從緩存中獲取對應的RootBeanDefinition定義。
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
// Step2:本地緩存中不存在。
if (mbd == null) {
// Step2.1:判斷當前BeanDefinition是否存在父BeanDefinition,如果不存在父BeanDefinition。
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
// Step2.1.1:實現了RootBeanDefinition接口,則拿BeanDefinition克隆一個RootBeanDefinition
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
// Step2.1.2:直接使用當前BeanDefinition創建一個對應的RootBeanDefinition定義。
mbd = new RootBeanDefinition(bd);
}
}
else {
// Child bean definition: needs to be merged with parent.
// Step2.2:存在父BeanDefinition,獲取父BeanDefinition對應的名字
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
// Step2.3:判斷當前BeanName和父BeanName不同,則根據父beanName獲取父BeanDefinition定義
if (!beanName.equals(parentBeanName)) {
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
// Step2.4:獲取父BeanFactory,如果父BeanFactory實現了ConfigurableBeanFactory接口,使用父BeanFactory獲取父BeanDefinition
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
// Step2.3:使用父BeanDefinition創建一個RootBeanDefinition定義,然後將當前BeanDefinition(子BeanDefinition)的屬性覆蓋上去。
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
// Set default singleton scope, if not configured before.
// Step2.4:設置scope屬性,默認的都是單例的。
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
// Step2.5:對外部傳進來的BeanDefinition設置scope屬性。
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
// Step2.6:將創建出來的RootBeanDefinition定義回種到本地緩存裏面。
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
// Step3:返回創建好的RootBeanDefinition定義。
return mbd;
}
}
獲取當前
BeanDefinition
對應的父BeanDefinition
對應的beanName
。
// 接着看看根據父beanName獲取對應的名字
protected String transformedBeanName(String name) {
// BeanFactoryUtils.transformedBeanName這個操作就是將FactoryBean的前綴去掉。
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
// 從別名map裏面獲取對應的beanName,返回別名對應的真實beanName。
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
拿到了
父beanName
,根據父beanName
獲取對應的BeanDefinition
定義。
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
// Step1. 獲取別名對應的真實beanName。
String beanName = transformedBeanName(name);
// Efficiently check whether bean definition exists in this factory.
// Step2:如果當前的BeanFactory不存在BeanDefinition定義 && 父BeanFactory實現了ConfigurableBeanFactory,則從父BeanFactory裏面獲取對應的RootBeanDefinition定義。
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
}
// Resolve merged bean definition locally.
// Step3:沒取到,則新創建。
return getMergedLocalBeanDefinition(beanName);
}
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
// Step1:從mergedBeanDefinitions緩存優先獲取,取到則直接返回。
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
// Step2:如果沒有取到,則根據當前的beanName獲取對應的beanDefinition定義,然後在遞歸調用getMergedBeanDefinition()方法獲取對應的RootBeanDefinition定義。
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
以上內容稍微繞點,仔細看兩遍應該也比較好懂,總結一下就是如果當前
BeanDefinition
存在父BeanDefinition
,則先獲取到父BeanDefinition
,然後在將當前BeanDefinition
的屬性覆蓋到父BeanDefinition
上,然後創建對應的RootBeanDefinition
返回。到此我們得到了RootBeanDefinition
定義,接下來看看beanName
對應的實例是否是FactoryBean
。
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
// Step1:獲取真實的beanName
String beanName = transformedBeanName(name);
// Step2:獲取beanName對應的bean實例
Object beanInstance = getSingleton(beanName, false);
// Step3:如果獲取到了對應的bean實例,則直接判斷其是否實現了FactoryBean接口,如果是則認爲是FactoryBean。
if (beanInstance != null) {
return (beanInstance instanceof FactoryBean);
}
// No singleton instance found -> check bean definition.
// Step4:如果當前BeanFactory裏面不存在對應的bean實例,則從父BeanFactory裏面獲取。
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
// Step5:當前BeanFactory存在,則選獲取對應RootBeanDefinition定義,獲取對應的beanType,根據beanType判斷是否是一個FactoryBean。
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
接着來看看
getSingleton()
是怎麼獲取beanName對應的bean實例的。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Step1:從singletonObjects緩存中獲取對象
Object singletonObject = this.singletonObjects.get(beanName);
// Step2:如果從緩存中沒取到 && beanName對應的bean實例正在創建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// Step2.1:從earlySingletonObjects緩存中獲取對應的bean實例
singletonObject = this.earlySingletonObjects.get(beanName);
// Step2.2:從緩存中沒有取到 && allowEarlyReference爲true
if (singletonObject == null && allowEarlyReference) {
// Step2.2.1:從singletonFactories緩存中獲取bean實例,如果能獲取到,將bean實例回種到前兩個緩存中,然後將bean實例返回。
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
// Step3:返回bean實例
return singletonObject;
}
再來看看
isFactoryBean()
是怎麼預測beanType
是否是FactoryBean
的。
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
// Step1:根據beanName和RootBeanDefinition獲取一個bean類型。
Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
// Step2:如果有對應的bean類型 && 如果bean類型是通過FactoryBean分配的,則認爲是一個FactoryBean。isAssignableFrom調用的是一個native方法。
return (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
}
總結
來總結一下本篇文章裏面遇到的幾個本地緩存。
beanDefinitionMap
:存放BeanDefinition
定義mergedBeanDefinitions
:存放RootBeanDefinition
定義singletonObjects
:存放bean實例,相當於bean實例的一級緩存earlySingletonObjects
:存放bean實例,相當於bean實例的二級緩存singletonFactories
:存放bean實例對應的BeanFactory,通過BeanFactory
創建相應的bean實例,相當於bean實例的三級緩存singletonsCurrentlyInCreation
:存放當前正在創建的bean實例
到此,我們遍歷了每個beanName
拿到了對應的RootBeanDefinition
定義,然後判斷了beanName
對應的bean實例是否是一個FactoryBean
。下一篇文章來分析根據beanName獲取對應的bean實例。
歡飲關注我,一起學習