說明:本文只介紹簡單的bean實例化過程体谒,沒有注入抒痒,沒有代理等等
實例
代碼
@Service
public class GoodsService {
public List<String> list() {
return Arrays.asList("apple");
}
}
@Configuration
@ComponentScan("com.yunfan.bean.instantiation.simple")
public class SimpleConfig {
}
public class MainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SimpleConfig.class);
GoodsService goodsService = (GoodsService) applicationContext.getBean("goodsService");
System.out.println(goodsService.list());
}
}
運行結(jié)果
> Task :spring-study:MainTest.main()
[apple]
spring Bean 實例化過程
本文只針對 實例
中 GoodsService
實例化過程進行描述傀广,實例化前簡單描述:spring 把 GoodsService 類信息保存到BeanDefinition伪冰,實例化時從BeanDefinition中讀取類信息進行實例化
1贮聂、實例化開始
首先打開spring源碼 DefaultListableBeanFactory
類的preInstantiateSingletons
方法 , 全路徑:org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 獲取所有BeanDefinition的集合
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 觸發(fā)所有非惰性單例bean的初始化…
for (String beanName : beanNames) {
// 獲取beanName對應(yīng)的 MergedBeanDefinition吓懈, MergedBeanDefinition合并了 子類和父類的信息
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// bd對應(yīng)的Bean實例:不是抽象類 && 是單例 && 不是懶加載
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 判斷beanName對應(yīng)的bean是否為FactoryBean
if (isFactoryBean(beanName)) {
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) {
getBean(beanName);
}
}
}
else {
// 如果beanName對應(yīng)的bean不是FactoryBean,只是普通Bean榕栏,通過beanName獲取bean實例
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
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();
}
}
}
}
首先,拷貝一個容器中所有 BeanDefinition
的名稱到beanNames的List集合中妨托, list中的內(nèi)容如圖:
對 beanNames
進行循環(huán)遍歷并進行實例化兰伤,此時我們只關(guān)心 goodsService
實例化過程敦腔。
第二符衔,獲取 goodsService
的 RootBeanDefinition
此時的 RootBeanDefinition
是一個 MergedLocalBeanDefinition
即和并了父類 相關(guān)信息的 BeanDefinition
判族,檢測bd對應(yīng)的Bean實例:不是抽象類 && 是單例 && 不是懶加載形帮,因為 goodsService
不是 FactoryBean
則直接執(zhí)行 getBean(beanName)
獲取bean 實例沃缘,詳細(xì)過程請查看 2槐臀、獲取bean ,getBean(beanName)
已經(jīng)把bean 實例化并緩存到單例池中,本方法的第二個for
循環(huán) 并并沒有對本次流程產(chǎn)生任何影響
2朝抖、獲取 bean
方法 getBean(beanName)
調(diào)用了 doGetBean
方法
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
方法 doGetBean
的全路徑是 org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 返回bean名稱治宣,去掉工廠取消引用前綴侮邀,并將別名解析為規(guī)范名稱绊茧。
final String beanName = transformedBeanName(name);
Object bean;
// 首先檢查單例緩存中手動注冊的單例對象华畏。(此處會涉及到注入的邏輯亡笑,本次沒有注入不過多關(guān)注)况芒,因為goodsService還沒有被創(chuàng)建所以此處sharedInstance為null
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
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");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 緩存中沒有耐版,創(chuàng)建這個bean實例:
// 如果該bean正在創(chuàng)建則拋出異常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 檢查這個父工廠中是否存在bean定義粪牲。本次執(zhí)行過程中parentBeanFactory 為 null
BeanFactory parentBeanFactory = getParentBeanFactory();
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);
}
}
if (!typeCheckOnly) {
// 標(biāo)記bean要創(chuàng)建了: 從 mergedBeanDefinitions 中刪除落君,在 alreadyCreated 中添加
// 讓bean定義重新合并绎速,現(xiàn)在我們實際上是在創(chuàng)建bean…以防在此期間它的一些元數(shù)據(jù)發(fā)生變化纹冤。
// 并把 goodsService 加入到 alreadyCreated 集合中
markBeanAsCreated(beanName);
}
try {
// 重新合并 goodsService 以防在此期間它的一些元數(shù)據(jù)發(fā)生變化萌京。
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 檢查 MergedBeanDefinition知残,其實就是檢查 goodsService 是否為抽象類求妹,如果是則拋出異常
checkMergedBeanDefinition(mbd, beanName, args);
// 保證當(dāng)前bean所依賴的bean的初始化扒最。 (goodsService 沒有依賴注入吧趣,所以 dependsOn 為 null)
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 + "'");
}
// 為給定bean注冊一個從屬bean强挫,在銷毀給定bean之前銷毀它呆细。dep 和 beanName 分別在兩個Map中 建立關(guān)聯(lián)關(guān)系絮爷,表示他們之間的依賴關(guān)系
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 創(chuàng)建bean 實例 檢測是否是單例模式
if (mbd.isSingleton()) {
// 此處調(diào)用 getSingleton 方法 傳遞了兩個參數(shù)坑夯,一個是 beanName, 另一個是 ObjectFactory 的實現(xiàn)類柜蜈,ObjectFactory 只有一個抽象方法 getObject() 淑履,所以當(dāng)執(zhí)行到 ObjectFactory.getObject() 時秘噪,其實執(zhí)行的是 createBean(beanName, mbd, args);
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
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;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
首先贯要,轉(zhuǎn)換 bean 的名稱崇渗,去掉工廠引用前綴宅广,并將別名解析為規(guī)范名稱跟狱。因為 goodsService
沒有使用別名并且是一個普通的類驶臊,所以最終轉(zhuǎn)換的結(jié)果還是 goodsService
关翎。
第二纵寝,從緩存中獲取共享實例爽茴,因為 goodsService
是首次創(chuàng)建所以 Object sharedInstance = null
進入到 else 分支
第三室奏,檢測如果 goodsService
正在實例化則拋出異常
第四窍奋,獲取父工廠江场,這里邊拋出一個問題:spring的父址否、子 工廠佑附? 當(dāng)前 parentBeanFactory = null
, 所以不走 if
分支音同,走 else
分支
第五权均,標(biāo)記 bean
即 goodsService
要被創(chuàng)建叽赊, 從 mergedBeanDefinitions
集合中刪除(讓bean定義重新合并必指,現(xiàn)在是在創(chuàng)建bean…以防在此期間它的一些元數(shù)據(jù)發(fā)生變化。) 谱邪,加入到 alreadyCreated
集合中
protected void markBeanAsCreated(String beanName) {
if (!this.alreadyCreated.contains(beanName)) {
synchronized (this.mergedBeanDefinitions) {
if (!this.alreadyCreated.contains(beanName)) {
// 讓bean定義重新合并惦银,現(xiàn)在我們實際上是在創(chuàng)建bean…以防在此期間它的一些元數(shù)據(jù)發(fā)生變化扯俱。
clearMergedBeanDefinition(beanName);
this.alreadyCreated.add(beanName);
}
}
}
}
第六,重新合并 MergedBeanDefinition
并檢測是不是抽象類
第七读存,獲取 goodsService
初始化所需要的依賴让簿,此時 String[] dependsOn = null
第八尔当,判斷 goodsService
是否為單例 mbd.isSingleton() = true
, 所以調(diào)用 getSingleton(String beanName, ObjectFactory<?> singletonFactory)
方法椭迎, 下面的代碼 是 ObjectFactory
接口的實現(xiàn)類缴阎,大括號 {...}
中便是 T getObject()
的實現(xiàn)方法药蜻,即調(diào)用 singletonFactory.getObject()
方法時 便是執(zhí)行大括號里邊的代碼 语泽。獲取單例的具體流程請查看 **3踱卵、獲取單例對象 **
() -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
此處可以獲取單例對象
第八,調(diào)用 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
getObjectForBeanInstance
會先調(diào)用 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getObjectForBeanInstance
在該方法中 需要注意 registerDependentBean(beanName, currentlyCreatedBean);
這一行西饵,當(dāng)然眷柔,本次流程不會執(zhí)行這行代碼,然后調(diào)用 org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance
這個方法鞠评,在本次流程中bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
這行代碼并沒有對 sharedInstance
做任何修改剃幌。返回單例對象
3牛郑、獲取單例對象
根據(jù) beanName
名稱返回注冊的單例對象,如果沒有則創(chuàng)建并注冊一個新的單例對象钉答。方法的全路徑名是 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 判斷當(dāng)前是否正在銷毀單例bean集合,如果是則拋出異常
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 檢測創(chuàng)建的bean 是否在排除創(chuàng)建的集合中(如果在則拋出異常) 和 將beanName 加入 singletonsCurrentlyInCreation (正在創(chuàng)建的bean的集合)
beforeSingletonCreation(beanName);
boolean newSingleton = false;
// 被抑制的異常列表
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// singletonFactory 生產(chǎn)bean
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 把實例放入緩存中
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
首先惶楼,加同步鎖何陆,再次從單例緩存池 singletonObjects
中獲取單例贷盲,如果不為null 則直接返回巩剖,此時為 null
第二,判斷當(dāng)前是否正在銷毀 單例 鞠鲜,如果是則拋出異常
第三镊尺,檢測創(chuàng)建的bean 是否在排除創(chuàng)建的集合中(如果在則拋出異常)庐氮, 將beanName
加入 singletonsCurrentlyInCreation
(正在創(chuàng)建的bean的集合)
第四仙畦,執(zhí)行 singletonObject = singletonFactory.getObject();
即 2慨畸、獲取bean 中 第八 步 的 lambda 表達式寸士, 即 執(zhí)行 createBean(beanName, mbd, args)
該方法的具體執(zhí)行流程請查看 4、創(chuàng)建bean婶博,這個行代碼將會獲得單例對象 singletonObject = GoodsService@1654
并設(shè)置 newSingleton = true;
第五凡人,執(zhí)行 afterSingletonCreation(beanName)
將 beanName 從 singletonsCurrentlyInCreation
集合中移除
第六,執(zhí)行 addSingleton(beanName, singletonObject)
該方法的代碼如下:
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
返回單例對象
4忠荞、解析bean并首次調(diào)用后置處理器
該方法執(zhí)行單例創(chuàng)建前的一次后置處理器,返回一個對象碧绞,如果該對象不為null讥邻,則直接返回兴使, 如果為 null 則執(zhí)行 doCreateBean
方法,完成真正的單例的創(chuàng)建
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 解析beanName對應(yīng)的Bean的類型
// resolvedClass = com.yunfan.bean.instantiation.simple.GoodsService
// mbd.hasBeanClass() = true
// mbd.getBeanClassName() = com.yunfan.bean.instantiation.simple.GoodsService
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
// 如果resolvedClass存在汰寓,并且mdb不存在beanClass即類型不是Class有滑,并且mdb的beanClassName不為空(則代表beanClass存的是Class的name),
// 則使用mdb深拷貝一個新的RootBeanDefinition副本嵌削,并且將解析的Class賦值給拷貝的RootBeanDefinition副本beanClass屬性毛好,
// 該拷貝副本取代mdb用于后續(xù)的操作
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
// 對override屬性進行標(biāo)記及驗證
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 實例化前的處理,給beanpostprocessor(InstantiationAwareBeanPostProcessor)一個機會返回代理對象來替代真正的bean實例,達到“短路”效果
// 第一次調(diào)用后置處理器
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 如果bean不為空飒箭,則會跳過Spring默認(rèn)的實例化過程,直接使用返回的bean
// 此時 bean = null
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 創(chuàng)建Bean實例(真正創(chuàng)建Bean的方法)
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
// 返回創(chuàng)建的Bean實例
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
首先,解析beanName(goodsService
)對應(yīng)的Bean的類型膝迎,resolvedClass = com.yunfan.bean.instantiation.simple.GoodsService
第二靡馁,對override屬性進行標(biāo)記及驗證
第三呢堰,實例化前調(diào)用 beanpostprocessor
( InstantiationAwareBeanPostProcessor
) 后置處理器返回代理對象來替代真正的bean實例,第一次實例化前調(diào)用 后置處理器咧欣,返回結(jié)果 Object bean = null
繼續(xù)向下執(zhí)行浅缸,如果bean 不為 null 則直接返回。
第四魄咕,調(diào)用 doCreateBean
方法創(chuàng)建單例衩椒,該方法是真正的創(chuàng)建單例,然后返回單例哮兰。想要了解 doCreateBean
的具體流程請查看 5毛萌、真正創(chuàng)建bean單例, 返回單例
5喝滞、創(chuàng)建 bean 單例
該方法實際創(chuàng)建指定的bean阁将。在這一點上,預(yù)創(chuàng)建處理已經(jīng)發(fā)生了右遭,例如檢查{@code postProcessBeforeInstantiation}回調(diào)做盅。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 新建Bean包裝類
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 如果是FactoryBean,則需要先移除未完成的FactoryBean實例的緩存
// 因為 goodsService 是一個普通的類窘哈,所以此處instanceWrapper = null
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 根據(jù)beanName吹榴、mbd、args滚婉,使用對應(yīng)的策略創(chuàng)建Bean實例图筹,并返回包裝類BeanWrapper
/*
* 第二次調(diào)用后置處理器
* 創(chuàng)建bean實例,并將實例放在包裝類BeanWrapper中返回
* 1满哪、通過工廠方法創(chuàng)建bean實例
* 2婿斥、通過構(gòu)造方法自動注入創(chuàng)建bean實例
* 3劝篷、通過無參構(gòu)造器創(chuàng)建bean實例
* */
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 拿到創(chuàng)建好的Bean實例
final Object bean = instanceWrapper.getWrappedInstance();
// 拿到Bean實例的類型
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 允許后處理程序修改合并的bean定義。
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 應(yīng)用后置處理器MergedBeanDefinitionPostProcessor民宿,允許修改MergedBeanDefinition娇妓,
// Autowired注解正是通過此方法實現(xiàn)注入類型的預(yù)解析
// 允許后置處理器修改合并的bean定義 MergedBeanDefinitionPostProcessor
// 第三次調(diào)用后置處理器
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 急切地緩存單例,以便能夠解析循環(huán)引用活鹰,甚至在由生命周期接口(如BeanFactoryAware)觸發(fā)時也是如此哈恰。
// 判斷是否需要提早曝光實例:單例 && 允許循環(huán)依賴 && 當(dāng)前bean正在創(chuàng)建中
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");
}
// 提前曝光beanName的ObjectFactory,用于解決循環(huán)引用
// 應(yīng)用后置處理器SmartInstantiationAwareBeanPostProcessor志群,允許返回指定bean的早期引用着绷,若沒有則直接返回bean
// 解決循環(huán)依賴 SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference
// 第四次調(diào)用后置處理器
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 初始化bean實例。
Object exposedObject = bean;
try {
// 對bean進行屬性填充锌云;其中荠医,可能存在依賴于其他bean的屬性,則會遞歸初始化依賴的bean實例
// 第五次桑涎、第六次調(diào)用后置處理器
populateBean(beanName, mbd, instanceWrapper);
// 對bean進行初始化
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);
}
}
if (earlySingletonExposure) {
// 如果允許提前曝光實例彬向,則進行循環(huán)依賴檢查
Object earlySingletonReference = getSingleton(beanName, false);
// earlySingletonReference只有在當(dāng)前解析的bean存在循環(huán)依賴的情況下才會不為空
if (earlySingletonReference != null) {
if (exposedObject == bean) {
// 如果exposedObject沒有在initializeBean方法中被增強,則不影響之前的循環(huán)引用
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 如果exposedObject在initializeBean方法中被增強 && 不允許在循環(huán)引用的情況下使用注入原始bean實例
// && 當(dāng)前bean有被其他bean依賴
// 拿到依賴當(dāng)前bean的所有bean的beanName數(shù)組
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 嘗試移除這些bean的實例攻冷,因為這些bean依賴的bean已經(jīng)被增強了娃胆,他們依賴的bean相當(dāng)于臟數(shù)據(jù)
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
// 移除失敗的添加到 actualDependentBeans
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
// 如果存在移除失敗的,則拋出異常等曼,因為存在bean依賴了“臟數(shù)據(jù)”
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.");
}
}
}
}
// 將bean注冊為一次性的里烦。
try {
// 注冊用于銷毀的bean,執(zhí)行銷毀操作的有三種:自定義destroy方法禁谦、DisposableBean接口胁黑、DestructionAwareBeanPostProcessor
// 將bean注冊為可以銷毀 DestructionAwareBeanPostProcessor bean的銷毀后置處理器
// 第九次調(diào)用后置處理器
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
// 完成創(chuàng)建并返回
return exposedObject;
}
首先,先移除未完成的FactoryBean實例的緩存州泊,因為 goodsService
是一個普通的bean 别厘,所以 this.factoryBeanInstanceCache.remove(beanName)
執(zhí)行的結(jié)果為 null
。
第二拥诡,創(chuàng)建 bean
實例触趴,調(diào)用 createBeanInstance
方法。代碼如下:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 確保此時bean類已經(jīng)被解析渴肉。
// beanClass = class com.yunfan.bean.instantiation.simple.GoodsService
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
// beanClass不為空 && beanClass不是公開類(不是public修飾) && 該bean不允許訪問非公共構(gòu)造函數(shù)和方法冗懦,則拋異常
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// 返回創(chuàng)建bean實例的回調(diào)(如果有的話)。
// instanceSupplier = null
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果存在工廠方法則使用工廠方法實例化bean對象
// mbd.getFactoryMethodName() = null
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
// 英文注釋翻譯:重新創(chuàng)建相同的bean時的快捷方式…
// resolved: 構(gòu)造函數(shù)或工廠方法是否已經(jīng)解析過
boolean resolved = false;
// autowireNecessary: 是否需要自動注入(即是否需要解析構(gòu)造函數(shù)參數(shù))
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// mbd.resolvedConstructorOrFactoryMethod 用于緩存已解析構(gòu)造函數(shù)或工廠方法的包可見字段仇祭。
// 此處 mbd.resolvedConstructorOrFactoryMethod = null
if (mbd.resolvedConstructorOrFactoryMethod != null) {
// 如果resolvedConstructorOrFactoryMethod緩存不為空披蕉,則將resolved標(biāo)記為已解析
resolved = true;
// 根據(jù)constructorArgumentsResolved判斷是否需要自動注入
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 因為 mbd.resolvedConstructorOrFactoryMethod = null 所以 resolved = false,程序不會進入 if 分支
if (resolved) {
// 如果已經(jīng)解析過,則使用resolvedConstructorOrFactoryMethod緩存里解析好的構(gòu)造函數(shù)方法
if (autowireNecessary) {
// 需要自動注入没讲,則執(zhí)行構(gòu)造函數(shù)自動注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 否則使用默認(rèn)的構(gòu)造函數(shù)進行bean的實例化
return instantiateBean(beanName, mbd);
}
}
// 應(yīng)用后置處理器SmartInstantiationAwareBeanPostProcessor眯娱,可以得到bean的候選構(gòu)造函數(shù),如@Autowire 注解的構(gòu)造方法爬凑, 然后使用該構(gòu)造函數(shù)進行創(chuàng)建對象徙缴。
// 自動裝配的候選者構(gòu)造器 SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
// 第二次調(diào)用后置處理器,這個方法用來推斷構(gòu)造函數(shù)嘁信,實際使用的實現(xiàn)SmartInstantiationAwareBeanPostProcessor接口的AutowiredAnnotationBeanPostProcess后置處理器去做的于样。
// 此處 ctors = null
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// AutowireMode設(shè)置為3,采用構(gòu)造器貪婪模式
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 如果ctors不為空 || mbd的注入方式為AUTOWIRE_CONSTRUCTOR || mdb定義了構(gòu)造函數(shù)的參數(shù)值 || args不為空潘靖,則執(zhí)行構(gòu)造函數(shù)自動注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// 默認(rèn)構(gòu)造的首選構(gòu)造函數(shù) ctors = null
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 沒有特殊處理穿剖,則使用默認(rèn)的構(gòu)造函數(shù)進行bean的實例化
// 即無參構(gòu)造器 通過反射調(diào)用無參構(gòu)造函數(shù)進行創(chuàng)建
return instantiateBean(beanName, mbd);
}
在 createBeanInstance
方法中有一個第二次調(diào)用后置處理器,需要注意一下卦溢,即Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
這個方法用來推斷構(gòu)造函數(shù)糊余,實際使用的實現(xiàn)SmartInstantiationAwareBeanPostProcessor
接口的AutowiredAnnotationBeanPostProcess
后置處理器去做的。
第三单寂,第三次調(diào)用后置處理器 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
該方法實際調(diào)用了 MergedBeanDefinitionPostProcessor的
方法:postProcessMergedBeanDefinition
啄刹,用來緩存注解信息。
第四凄贩,即第四次調(diào)用后置處理器 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
調(diào)用了 SmartInstantiationAwareBeanPostProcessor
后置處理器的 getEarlyBeanReference(exposedObject, beanName)
方法 ,這個方法是來解決循環(huán)依賴問題的
第五袱讹,即第五次調(diào)用后置處理器, 在 populateBean(beanName, mbd, instanceWrapper);
方法里調(diào)用了后置處理器 InstantiationAwareBeanPostProcessor
的方法 postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)
判斷是否需要填充屬性疲扎,goodsService 需要填充的屬性個數(shù)為零,但并不是不允許修改bean的屬性捷雕,所以不會忽略直接返回
第六椒丧,即第六次調(diào)用后置處理器,在 populateBean(beanName, mbd, instanceWrapper);
方法里調(diào)用了后置處理器 InstantiationAwareBeanPostProcessor
的方法 postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
進行屬性填充前的處理
第七救巷,即第七次調(diào)用后置處理器壶熏,在方法exposedObject = initializeBean(beanName, exposedObject, mbd)
中 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
調(diào)用了 BeanPostProcessor
的方法 postProcessBeforeInitialization(result, beanName)
對bean實例進行包裝
第八,即第七次調(diào)用后置處理器浦译,在方法exposedObject = initializeBean(beanName, exposedObject, mbd)
中 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
調(diào)用了 BeanPostProcessor
的方法 postProcessAfterInitialization(result, beanName)
第九棒假,即第九次調(diào)用后置處理器,在方法 registerDisposableBeanIfNecessary(beanName, bean, mbd);
中 將bean注冊為可以銷毀 DestructionAwareBeanPostProcessor
bean的銷毀后置處理器