1. 引言
我們可以通過ApplicationContext
創(chuàng)建IOC
容器,它有很多個子類匿级,下面通過它的子類AnnotationConfigApplicationContext
的創(chuàng)建來分析下IOC
容器是如何創(chuàng)建并進行初始化的蟋滴。
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(AopConfig.class);
AnnotationConfigApplicationContext
創(chuàng)建的源碼如下:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
這里refresh()
方法是重點,它的源碼是:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
} catch (BeansException ex) {
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
refresh()
方法中每一行都很重要痘绎,我們依次來進行分析津函。
2. prepareRefresh()
該方法主要是為IOC
容器啟動做一些準備工作,設(shè)置容器的啟動時間孤页,closed
和active
標識尔苦。
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// 空方法,留給子類擴展行施,初始化 placeholder property
initPropertySources();
// 驗證一些必須的屬性
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
} else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}
這里有個可以擴展的點允坚,我們可以通過重寫ApplicationContext
來對自定義環(huán)境變量驗證,要求必須存在某個環(huán)境變量時才能啟動IOC
容器蛾号。具體細節(jié)可以參考:https://blog.csdn.net/boling_cavalry/article/details/81474340
3. obtainFreshBeanFactory
obtainFreshBeanFactory()
主要是獲取BeanFactory
稠项,在獲取BeanFactory
之前會先創(chuàng)建BeanFactory
。
先來看看BeanFactory
是在什么地方創(chuàng)建的鲜结,我們回到AnnotationConfigApplicationContext
創(chuàng)建的地方展运。
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this(); // 調(diào)用無參的構(gòu)造
register(annotatedClasses);
refresh();
}
無參構(gòu)造器默認會隱式地調(diào)用父類的無參構(gòu)造器方法活逆,AnnotationConfigApplicationContext
的父類是GenericApplicationContext
,而BeanFactory
就是在GenericApplicationContext
的構(gòu)造方法中創(chuàng)建出來的拗胜。
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
再回到obtainFreshBeanFactory()
方法蔗候,它主要做了3件事情:
- 設(shè)置
refreshed
屬性,通過AtomicBoolean
的cas
操作控制refresh()
方法只會被調(diào)用一次埂软; - 給
beanFactory
設(shè)置serializationId
锈遥; - 返回
beanFactory
對象,實際類型為DefaultListableBeanFactory
勘畔。
4.prepareBeanFactory
prepareBeanFactory(beanFactory)
主要功能是給上一步獲取到的beanFactory
進行一些屬性的設(shè)置所灸。主要設(shè)置了以下屬性:
-
BeanFactory
的類加載器、支持表達式解析器咖杂; - 添加了兩個
BeanPostProcessor
:ApplicationContextAwareProcessor
、ApplicationListenerDetector
蚊夫; - 設(shè)置忽略的自動裝配接口:
EnvironmentAware
诉字,EmbeddedValueResolverAware
,ResourceLoaderAware
知纷,ApplicationEventPublisherAware
壤圃,MessageSourceAware
,ApplicationContextAware
琅轧, 在依賴注入的時候忽略這些接口伍绳,也就是這些指定的接口不會被注入進去。 - 注冊可以解析的自動裝配:
BeanFactory
,ResourceLoader
,ApplicationEventPublisher
,ApplicationContext
乍桂,這些類可以在任何地方直接注入冲杀; - 添加類加載期織入(
LoadTimeWeaver
)的AspectJ
; - 注冊一些組件:
environment
睹酌、systemProperties
权谁、systemEnvironment
。
在Java 語言中憋沿,從織入切面的方式上來看旺芽,存在三種織入方式:
編譯期織入、類加載期織入和運行期織入
辐啄。編譯期織入是指在Java編譯期采章,采用特殊的編譯器,將切面織入到Java類中壶辜;而類加載期織入則指通過特殊的類加載器悯舟,在類字節(jié)碼加載到JVM時,織入切面砸民;運行期織入則是采用CGLib工具或JDK動態(tài)代理進行切面的織入图谷。
AspectJ提供了兩種切面織入方式翩活,第一種通過特殊編譯器,在編譯期便贵,將AspectJ語言編寫的切面類織入到Java類中菠镇,可以通過一個Ant或Maven任務(wù)來完成這個操作;第二種方式是類加載期織入承璃,也簡稱為LTW(Load Time Weaving)利耍。
5. postProcessBeanFactory
postProcessBeanFactory(beanFactory)
是個空方法。子類可以通過重寫這個方法盔粹,在BeanFactory
創(chuàng)建并預(yù)準備完成之后做些擴展工作隘梨。該方法在spring-web
下有對其進行重寫。
6. invokeBeanFactoryPostProcessors
invokeBeanFactoryPostProcessors(beanFactory)
主要用來執(zhí)行BeanFactoryPostProcessors
舷嗡,它會將bean
的信息轉(zhuǎn)化成BeanDefinition
轴猎。
BeanFactoryPostProcessors
是BeanFacotry
的后置處理器,在BeanFactory
標準初始化之后執(zhí)行进萄,它是Spring
提供的眾多擴展點之一捻脖。BeanFacotry
后置處理器有兩個接口:BeanFactoryPostProcessor
和BeanDefinitionRegistryPostProcessor
。
invokeBeanFactoryPostProcessors
方法整體流程如下:
先執(zhí)行`BeanDefinitionRegistryPostProcessor`接口:
1. 獲取所有的`BeanDefinitionRegistryPostProcessor`中鼠;
2. 看先執(zhí)行實現(xiàn)了`PriorityOrdered`優(yōu)先級接口的`BeanDefinitionRegistryPostProcessor`可婶、 `postProcessor.postProcessBeanDefinitionRegistry(registry)`
3. 在執(zhí)行實現(xiàn)了`Ordered`順序接口的`BeanDefinitionRegistryPostProcessor`;
`postProcessor.postProcessBeanDefinitionRegistry(registry)`
4. 最后執(zhí)行沒有實現(xiàn)任何優(yōu)先級或者是順序接口的`BeanDefinitionRegistryPostProcessors`援雇;
`postProcessor.postProcessBeanDefinitionRegistry(registry)`
再執(zhí)行`BeanFactoryPostProcessor`的方法
1. 獲取所有的`BeanFactoryPostProcessor`
2. 看先執(zhí)行實現(xiàn)了`PriorityOrdered`優(yōu)先級接口的`BeanFactoryPostProcessor`矛渴、
`postProcessor.postProcessBeanFactory()`
3. 在執(zhí)行實現(xiàn)了`Ordered`順序接口的`BeanFactoryPostProcessor`;
`postProcessor.postProcessBeanFactory()`
4. 最后執(zhí)行沒有實現(xiàn)任何優(yōu)先級或者是順序接口的`BeanFactoryPostProcessor`惫搏;
`postProcessor.postProcessBeanFactory()`
7. registerBeanPostProcessors
registerBeanPostProcessors(beanFactory)
方法用來向beanFactory
注冊BeanPostProcessor
(bean的后置處理器)具温,這又是Spring
容器提供的眾多擴展點之一。Bean
的后置處理器共有5個接口:
BeanPostProcessor
DestructionAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor
MergedBeanDefinitionPostProcessor
這5個接口中的方法會在IOC
容器啟動過程中不同的時機被回調(diào)筐赔。
和BeanFacotryPostProcessor
類似桂躏,BeanPostProcessor
也能夠通過實現(xiàn)PriorityOrdered
、Ordered
接口進行排序川陆。
registerBeanPostProcessors(beanFactory)
方法中將BeanFacotryPostProcessor
分成priorityOrderedPostProcessors
剂习、internalPostProcessors
、orderedPostProcessorNames
较沪、nonOrderedPostProcessorNames
4 類鳞绕,分好類之后再依次添加BeanFactory
中。
priorityOrderedPostProcessor: 實現(xiàn)了`PriorityOrdered`接口的BeanPostProcessor尸曼;
orderedPostProcessorNames: 實現(xiàn)了`Ordered`接口的BeanPostProcessor们何;
nonOrderedPostProcessorNames: 沒有實現(xiàn)排序的BeanPostProcessor
internalPostProcessors: MergedBeanDefinitionPostProcessor接口
通過請求beanFactory.addBeanPostProcessor(postProcessor);
方法,向容器中添加bean
的后置處理器控轿。
8. initMessageSource
initMessageSource()
方法是向容器中注冊一個MessageSource
組件冤竹。MessageSource
主要作用是支持國際化拂封。
initMessageSource()
方法的主要邏輯是:
先看容器中是否有name
為messageSource
的MessageSource
的組件,
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent essageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
}
如果容器中沒有MessageSource
組件,則創(chuàng)建出來并注冊到beanFactory
中鹦蠕。
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
9. initApplicationEventMulticaster
initApplicationEventMulticaster()
主要對事件派發(fā)器(ApplicationEventMulticaster
)進行初始化冒签,即向beanFactory
注冊一個事件派發(fā)器。它的邏輯很很簡單钟病,就是先判斷容器中是否有name=applicationEventMulticaster
的bean萧恕,沒有的話就創(chuàng)建一個再向容器中注冊。
10. onRefresh
這個方法默認實現(xiàn)什么都沒有做肠阱,主要留給子類進行拓展票唆。
11. registerListeners
registerListeners()
將所有的ApplicationListener
進行注冊,并進行事件派發(fā)屹徘。它的主要邏輯:
- 獲取所有的
ApplicationListener
走趋; - 將每個監(jiān)聽器添加到事件派發(fā)器中;
- 如果存在早期應(yīng)用事件噪伊,則將其發(fā)布出去簿煌。
12. finishBeanFactoryInitialization
finishBeanFactoryInitialization(beanFactory)
是個重點方法,它會將所有非懶加載的單例對象進行實例化酥宴。
在AbstractApplicationContext#finishBeanFactoryInitialization
方法中啦吧,它最終會調(diào)用DefaultListableBeanFactory#preInstantiateSingletons
方法對剩下的單實例bean進行初始化,我們重點看看此方法。先貼一下源碼:
public void preInstantiateSingletons() throws BeansException {
// beanDefinitionNames在refresh()之前創(chuàng)建ApplicationContext的this()方法中進行設(shè)值
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 遍歷觸發(fā)所有非懶加載的單例bean進行初始化
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//單例鸵鸥、非抽象丽涩、非懶加載
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// bean是否為工廠bean,工廠bean需要加
if (isFactoryBean(beanName)) {
// 通過 &+beanName來獲取工廠bean本身藻懒,而beanName獲取的是FactoryBean創(chuàng)建的對象
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
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());
}
if (isEagerInit) {
// 獲取FactoryBean創(chuàng)建的bean對象
getBean(beanName);
}
}
}
else {
// 普通的單例bean獲取對象,實際會進行初始化
getBean(beanName);
}
}
}
// 觸發(fā)實現(xiàn)了SmartInitializingSingleton接口的afterSingletonsInstantiated方法
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
其中getBean()
方法是重點,我們需要重點關(guān)注诚啃。getBean()
是定義在AbstractBeanFactory
類中的方法,getBean()
方法最終會調(diào)用doGetBean()
方法(Spring中很多類似的風(fēng)格私沮,真正干活的都放在doXxx方法中)始赎。
在doGetBean
方法中會完成bean
的初始化,其大概邏輯是:先獲取緩存中保存的單實例Bean仔燕。如果能獲取到說明這個Bean之前被創(chuàng)建過(所有創(chuàng)建過的單實例Bean都會被緩存到名為singletonObjects
的map中)造垛,如果獲取不到就進行Bean的創(chuàng)建流程,而在每個Bean創(chuàng)建的過程中又會觸發(fā)各種BeanPostProcessor
的執(zhí)行晰搀。
12.1 獲取bean-doGetBean
下面來看看doGetBean
的源碼:
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// beanName轉(zhuǎn)換五辽,因為傳入的參數(shù)可以是alias,也可能是FactoryBean的name外恕,所以需要進行轉(zhuǎn)換
final String beanName = transformedBeanName(name);
Object bean;
// 嘗試從緩存中獲取bean杆逗,這里緩存有三級緩存乡翅,主要用來解決循環(huán)依賴問題
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// 原型模式,如果存在循環(huán)依賴罪郊,則拋出異常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 獲取父BeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
//如果當(dāng)前容器中沒有bean的定義信息蠕蚜,就從父容器中獲取
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
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);
}
}
// 如果不僅僅是做類型檢查,標記bean的狀態(tài)已經(jīng)創(chuàng)建排龄,即將beanName加入alreadyCreated集合中
if (!typeCheckOnly) {
// 這個方法使用了雙重檢測機制
markBeanAsCreated(beanName);
}
try {
// 如果存在父bean波势,則同時合并父bean的相關(guān)屬性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 檢查bean是否是抽象的,是的話就拋出異常
checkMergedBeanDefinition(mbd, beanName, args);
// 加載當(dāng)前bean依賴的bean
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 + "'");
}
// 緩存依賴調(diào)用
registerDependentBean(dep, beanName);
try {
getBean(dep);
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 處理單例bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 實際創(chuàng)建beand的地方
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
// 從單例緩存中移除
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// scope==prototype的bean 創(chuàng)建新的實例.
Object prototypeInstance = null;
try {
// 設(shè)置正在創(chuàng)建的狀態(tài)
beforePrototypeCreation(beanName);
// 創(chuàng)建bean
prototypeInstance = createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
// 返回對應(yīng)的實例
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
// 其他scope的bean
String scopeName = mbd.getScope();
// scope合法性校驗
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
} catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 如果對返回 bean 類型有要求橄维,則進行類型檢查尺铣,并按需做類型轉(zhuǎn)換
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
// 執(zhí)行類型轉(zhuǎn)換,轉(zhuǎn)換成期望的類型
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
} catch (TypeMismatchException ex) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
整個方法可以概括為:
1争舞、轉(zhuǎn)換Bean的名稱凛忿,獲取真正的beanName;
2竞川、檢查三級緩存中是否含有bean店溢,如果含有則實例化并返回對象,否則繼續(xù)流程委乌;
3床牧、如果當(dāng)前beanFactory中不存在需要的bean,則從父容器中獲取bean遭贸;
4戈咳、如果當(dāng)前bean存在依賴的bean,就遍歷初始化依賴的bean對象壕吹;
5著蛙、根據(jù)bean的作用域不同,對bean進行實例化耳贬,作用域分為:singleton踏堡、prototype和其他;
6咒劲、如果requiredType不為空顷蟆,則做類型校驗,如果需要類型和實際類型不一致腐魂,則做類型轉(zhuǎn)換帐偎;
7、返回bean對象挤渔。
12.2 bean的創(chuàng)建--createBean
上面doGetBean
方法中肮街,創(chuàng)建bean
的工作是調(diào)用AbstractAutowireCapableBeanFactory#createBean
來完成的,以下是createBean
的源碼(省略日志輸出和異常處理):
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 根據(jù)設(shè)置的class屬性或className來解析得到Class引用
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 處理lookup-method和replaced-method標簽
try {
mbdToUse.prepareMethodOverrides();
}
// 處理InstantiationAwareBeanPostProcessor判导,讓BeanPostProcessor先攔截返回代理對象
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
// 創(chuàng)建bean實例
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
}
該方法雖然叫createBean嫉父,但還不是真正創(chuàng)建bean的地方沛硅,它主要還是在做一些前期的準備工作,具體創(chuàng)建bean的方法是doCreateBean
绕辖。在看doCreateBean
方法之前摇肌,會調(diào)用resolveBeforeInstantiation()
方法。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// mbd是程序創(chuàng)建的且存在后置處理器
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 獲取最終的class引用仪际,如果是工廠方法則獲取工廠所創(chuàng)建的實例類型
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 調(diào)用實例化前置處理
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 調(diào)用初始化后置處理
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
可以看到如果InstantiationAwareBeanPostProcessor
中的實例化前置處理方法的返回值不為空围小,就會直接請求BeanPostProcessor
接口中的初始化后置處理方法。而如果這個方法的最終返回值bean
不為空树碱,則會跳過后續(xù)的doCreateBean
方法執(zhí)行(因為bean已經(jīng)創(chuàng)建完成了)肯适,從而形式短路。
12.2.1 doCreateBean
從上面的分析成榜,我們知道:createBean
只是在做創(chuàng)建bean之前的準備工作框舔,真正創(chuàng)建bean
的方法是doCreateBean
。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 如果是單例赎婚,嘗試獲取對應(yīng)的BeanWrapper.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// BeanWrapper為空刘绣,即bean未實例化,則創(chuàng)建bean實例
if (instanceWrapper == null) {
// 使用對應(yīng)的策略(工廠方法挣输、構(gòu)造函數(shù))創(chuàng)建bean實例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
// 應(yīng)用MergedBeanDefinitionPostProcessor
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 處理merged bean
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 檢查是否需要提前暴露纬凤,避免循環(huán)依賴
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 為避免循環(huán)依賴,在bean實例化完成之前撩嚼,將對應(yīng)的ObjectFactory添加到singletonFactories屬性中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 初始化Bean實例.
Object exposedObject = bean;
try {
// 對bean的屬性進行填充停士,注入屬性值
populateBean(beanName, mbd, instanceWrapper);
// 初始化Bean,調(diào)用各種初始化方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
} catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
} else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
// 再次驗證是否存在依賴關(guān)系
if (earlySingletonExposure) {
// 獲取單例bean绢馍,不允許早期引用
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 獲取依賴的bean name
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
// bean在創(chuàng)建完成之后向瓷,其依賴的bean一定是被創(chuàng)建了的
// 如果actualDependentBeans不為空肠套,則說明bean依賴的bean沒有完成創(chuàng)建舰涌,存在循環(huán)依賴
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
// 注冊DisposableBean
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
doCreateBean
方法概括起來,主要分為以下步驟:
1)你稚、`創(chuàng)建Bean實例`:createBeanInstance(beanName, mbd, args);利用工廠方法或者對象的構(gòu)造器創(chuàng)建出Bean實例瓷耙;
2)、applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName):調(diào)用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName);
3)刁赖、檢查是否需要提前曝光搁痛,避免循環(huán)依賴
4)、`Bean屬性賦值`:populateBean(beanName, mbd, instanceWrapper);
賦值之前:
1)宇弛、調(diào)用InstantiationAwareBeanPostProcessor后置處理器的postProcessAfterInstantiation()鸡典;
2)、調(diào)用InstantiationAwareBeanPostProcessor后置處理器的postProcessPropertyValues()枪芒;
賦值之后:
3)彻况、應(yīng)用Bean屬性的值谁尸,為屬性利用setter方法等進行賦值;
applyPropertyValues(beanName, mbd, bw, pvs);
5)纽甘、`Bean初始化`:initializeBean(beanName, exposedObject, mbd);
1)良蛮、【執(zhí)行Aware接口方法】invokeAwareMethods(beanName, bean); 執(zhí)行xxxAware接口的方法BeanNameAware\BeanClassLoaderAware\BeanFactoryAware
2)、【執(zhí)行后置處理器postProcessBeforeInitialization】applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); BeanPostProcessor.postProcessBeforeInitialization();
3)悍赢、【執(zhí)行初始化方法】invokeInitMethods(beanName, wrappedBean, mbd);
1)决瞳、是否是InitializingBean接口的實現(xiàn);執(zhí)行接口規(guī)定的初始化左权;
2)皮胡、是否自定義初始化方法;
4)赏迟、【執(zhí)行后置處理器postProcessAfterInitialization】applyBeanPostProcessorsAfterInitialization: BeanPostProcessor.postProcessAfterInitialization()胸囱;
6)、再次驗證是否存在循環(huán)依賴瀑梗;
7)烹笔、注冊 DisposableBean。
13.finishRefresh
finishRefresh()
完成IOC
容器的創(chuàng)建抛丽。
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// 初始化一個和生命周期相關(guān)的后置處理器LifecycleProcessor谤职,默認從容器中找,沒找到就創(chuàng)建一個
initLifecycleProcessor();
// 回調(diào)LifecycleProcessor的onRefresh方法
getLifecycleProcessor().onRefresh();
// 發(fā)布容器刷新完成事件
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
至此亿鲜,Spring
的IOC
容器就創(chuàng)建完畢允蜈。
寫了一天,有點寫不動了蒿柳。先這樣吧饶套,后續(xù)有精力再進行更新吧。