一弄息、回顧
上回講到……講到哪了……
先貼代碼回顧一下猬膨,找到其中唯一一行注釋吧尔崔!
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
//恭喜你找到了注釋答毫,是的,上次講到這兒了
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
}
catch (BeansException ex) {
……
}
finally {
……
resetCommonCaches();
}
}
}
上回講到季春,在BeanFactory創(chuàng)建和BeanDefinitions注冊完成后洗搂,spring對BeanFactory進行了一些相關的后續(xù)操作,如執(zhí)行BeanFactoryPostProcessors的方法载弄,注冊一些BeanPostProcessors耘拇,設置事件廣播器等等。今天來講一下重頭戲——finishBeanFactoryInitialization(beanFactory)宇攻,一起點進去看看吧惫叛。
二、finishBeanFactoryInitialization(beanFactory)
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化 conversion service 逞刷,不展開
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));
}
// Resolver相關嘉涌,不展開
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// AspectJ相關,不展開
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用暫時的類加載器
beanFactory.setTempClassLoader(null);
// 凍結配置夸浅,防止在初始化bean過程中出現干擾
beanFactory.freezeConfiguration();
// 初始化所有單例bean仑最,最關鍵的一步,進去看看
beanFactory.preInstantiateSingletons();
}
三题篷、preInstantiateSingletons()
由于代碼比較長词身,所以忽略一些無關緊要的代碼厅目,在看代碼之前番枚,先想一想,為什么BeanFactory需要初始化單例Bean损敷,有哪些單例Bean是需要在一開始就被初始化的葫笼?帶著這樣的問題來看源碼拗馒,會有更清晰的認知。
public void preInstantiateSingletons() throws BeansException {
// 這里獲取到了工廠里的所有的beanNames
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 要開始從萬花叢中找單例的beanDefinition了
for (String beanName : beanNames) {
//獲取BeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//找出非抽象非懶加載的單例beanDefinition
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//這里出現了一個新的概念,FactoryBean呈昔,很重要,之后講
if (isFactoryBean(beanName)) {
//對bean name加工友绝,用于區(qū)分普通bean和factory bean
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
//判斷當前FactoryBean是否是SmartFactoryBean的實現堤尾,這里不影響后續(xù)的閱讀,可以跳過迁客,因此省略了
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
......
}
else {
......
}
//getBean方法郭宝,這是重點
if (isEagerInit) {
getBean(beanName);
}
}
}
//若當前的beanDefinition不是factory bean,則直接調用getBean
else {
getBean(beanName);
}
}
}
// 到這里為止掷漱,所有的非懶加載的singleton beans已經完成了初始化
// 如果我們定義的單例bean是實現了SmartInitializingSingleton接口粘室,那么當他們在初始化后會在這里得到回調,就不展開了
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();
}
}
}
}
上面的代碼雖然冗長卜范,但其實可以發(fā)現其實初始化單例bean的關鍵就在于getBean方法衔统,其實也可以說,初始化所有bean的關鍵就在于getBean,因為在這里只不過是對bean的scope做了篩選先朦。
在對getBean做了解之前缰冤,先看看先前講到的FacotryBean是怎么回事
四、FactoryBean
將FactoryBean翻譯成中文喳魏,就是工廠Bean棉浸,也就是說,這個Bean在初始化以后會變成一個工廠刺彩,這樣就很好理解了~那么這個工廠Bean具體是干什么的迷郑?工廠用來生產什么東西?來看看這個類的注釋
/* Interface to be implemented by objects used within a {@link BeanFactory} which
* are themselves factories for individual objects. If a bean implements this
* interface, it is used as a factory for an object to expose, not directly as a
* bean instance that will be exposed itself.
*
* <p><b>NB: A bean that implements this interface cannot be used as a normal bean.</b>
* A FactoryBean is defined in a bean style, but the object exposed for bean
* references ({@link #getObject()}) is always the object that it creates.
*/
雖然我也看不懂英語创倔,但是不代表我不能翻譯嗡害,簡單來講,FactoryBean能夠生產并暴露獨特的Bean畦攘,而不是直接將FactoryBean本身暴露出來霸妹,這句話有一點抽象,你可以理解成政府(BeanFactory)建立(初始化)了一家棒冰廠家(FactoryBean)知押,用來生產棒冰給員工(開發(fā)者)降暑叹螟,你得知道員工需要的只是棒冰而并不是廠家本身。
因此罢绽,如果一個類實現了FactoryBean良价,那么你就不能把他當作一個普通Bean來使用明垢,此時打開你的腦洞,想象FactoryBean可以從一個其他的遠程項目中獲取一個對象來作為Bean實例返回史隆,或者更夸張一些泌射,遠程獲取的Bean甚至可以是一個服務熔酷,只需調用這個服務拒秘,便可以讓自己的項目功能瞬間完成躺酒,這讓你又多了一個小時額外的自主學習(摸魚)時間羹应,豈不快哉?
好了好了劫灶,到此為止本昏,是時候看看getBean了涌穆,前面提到getBean是初始化Bean的關鍵
五蒲犬、getBean(beanName)
getBean方法位于AbstractBeanFactory中原叮,該類提供了很多該方法的重載擂送,不過功能其實是一樣的——獲取bean實例嘹吨,來看看這次的主角getBean(String beanName)
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
跳轉到doGetBean,做好心理準備……不過也別擔心蟀拷,按著注釋一步步來问芬,不會有什么難度
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//傳來的name可能是帶$的FactoryBean或者別名此衅,要轉換一下,不展開了
final String beanName = transformedBeanName(name);
//該bean用來作為返回值墨微,關注一下
Object bean;
// 首先檢查是否為已經手動創(chuàng)建的單例bean
Object sharedInstance = getSingleton(beanName);
//若是已創(chuàng)建的單例bean欢嘿,則會判斷args炼蹦,args不為空表示創(chuàng)建一個新的bean并返回掐隐,比如讓FactoryBean返回一個新的bean
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
......
}
else {
......
}
}
//賦值給bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
//若是未創(chuàng)建的虑省,則進入下面的邏輯
else {
// 正在創(chuàng)建此 beanName 的 prototype 類型的 bean探颈,那么拋異常伪节,這往往是因為陷入了循環(huán)引用
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 檢查工廠中是否存在beanDefinition
BeanFactory parentBeanFactory = getParentBeanFactory();
//若當前工廠沒有怀大,檢查父工廠
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name);
//父工廠為AbstractBeanFactory實例潜慎,讓父工廠返回bean
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
//父工廠不是AbstractBeanFactory實例铐炫,且args不為空
else if (args != null) {
// 傳入args讓父工廠代理產生bean
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
//兩個條件都不滿足,代理到普通的getBean方法
else {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
//typeCheckOnly是傳參為false山涡,這里會進入到if語句中
if (!typeCheckOnly) {
//標記當前bean已經被創(chuàng)建
markBeanAsCreated(beanName);
}
//如果不需要父工廠處理竞穷,當前工廠就自己處理
try {
//獲取bean定義瘾带,由于bean中很可能有依賴項看政,所以管他叫MergedLocalBeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//檢查是否為abstract,很簡單不展開
checkMergedBeanDefinition(mbd, beanName, args);
// 獲取當前bean所依賴的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
//循環(huán)引用拋出異常
......
}
//注冊依賴關系嚷兔,后面會展開冒晰,可以先往下看
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, () -> {
//這里創(chuàng)建了Bean蒋情,很重要恕出,之后展開
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// 刪除緩存中的Bean
// 同時刪除所有接收了當前Bean的臨時引用的Bean
destroySingleton(beanName);
//拋出異常
throw ex;
}
});
//若創(chuàng)建Bean成功浙巫,則為bean賦值的畴,前面講到bean用來作為返回值
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//如果bean屬于prototype
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
//在創(chuàng)建bean之前的操作,比較簡單煎娇,不展開
beforePrototypeCreation(beanName);
//創(chuàng)建bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//和boefore操作差不都缓呛,也不展開
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//bean屬于其他域,操作和前面差不多痰憎,這塊就省略了
else {
......
}
}
catch (BeansException ex) {
//若bean產生失敗票髓,則進行清理,并拋出異常铣耘,較簡單洽沟,就是在表示已創(chuàng)建bean的Set集合中將當前beanName移除
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// requiredType是要檢索的bean的所需類型,若不為空蜗细,且類型匹配玲躯,則進行類型轉換
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.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
//返回Bean
return (T) bean;
}
值得一提的是spring加載bean的方式其實很有趣,當子容器在當前beanDefinitionMap中找不到beanDefinition時就會把任務丟給父容器去做鳄乏,如果父容器找不到跷车,還會丟給他的父容器去找密强,實在是有點坑爹的嫌疑,但其實這個遞歸的調用卻又很巧妙,每個容器只要做好自己分內的事即可地熄,將不屬于自己的任務向上拋出却特,層層向上處理轰绵,真是妙哉液样。下面是getBean方法中一些重要的相關操作澎怒,可以對著上面的代碼找到對應的實現
六琳状、registerDependentBean(dep, beanName)
在初始化一個bean時肮柜,需要將bean內的依賴與當前bean注冊一個依賴關系待讳,來看看spring為什么要注冊依賴關系,并且是怎么做的涂邀。在下面的代碼中找到dependentBeanMap和dependenciesForBeanMap观蜗,這是注冊關系的關鍵岸售。
找到兩者在源碼中的對應位置,看看他們是什么樣的
dependentBeanMap
/** Map between dependent bean names: bean name --> Set of dependent bean names */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
這里存儲的是被依賴者與依賴者的關系,比如User中有一項依賴叫Car复哆,那么dependentBeanMap存儲的就是carName:userName
dependenciesForBeanMap
/** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
這里就是和上面的反一反久免,userName:carName
現在就來看看代碼把~
/**
* Register a dependent bean for the given bean,
* to be destroyed before the given bean is destroyed.
* @param beanName the name of the bean
* @param dependentBeanName the name of the dependent bean
*/
public void registerDependentBean(String beanName, String dependentBeanName) {
String canonicalName = canonicalName(beanName);
synchronized (this.dependentBeanMap) {
//若被依賴項的依賴關系不存在,則創(chuàng)建一個
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
//添加依賴關系丁寄,若beanName:dependentBeanName已存在,則return
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
synchronized (this.dependenciesForBeanMap) {
//若被依賴項的依賴關系不存在豪筝,則創(chuàng)建一個
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
//添加依賴關系
dependenciesForBean.add(canonicalName);
}
}
其實可以從方法上的注釋即可知道:“to be destroyed before the given bean is destroyed”峻黍,即“被依賴項會在給定的bean被銷毀之前被銷毀”仑扑,spring這么做的目的就很清晰了——為了GC蛛碌。
再來討論一下里面的這一句:
//添加依賴關系,若beanName:dependentBeanName已存在辖源,則return
if (!dependentBeans.add(dependentBeanName)) {
return;
}
為什么如果被依賴項與依賴項的關系已建立蔚携,就不用再建立依賴項與被依賴項的關系?……這聽起來很拗口克饶,但確實是這么回事兒酝蜒。想知道答案可以去同一個類中registerContainedBean方法去看看就能明白啦~好了,現在回到五繼續(xù)看后面的代碼把
七矾湃、createBean(beanName, mbd, args)
第三個參數 args 數組代表創(chuàng)建實例需要的參數亡脑,就是給構造方法用的參數,或者是工廠 Bean 的參數。不過要注意的是在初始化階段霉咨,args 是 null蛙紫。create Bean的實現在AbstractAutowireCapableBeanFactory類中
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
......
RootBeanDefinition mbdToUse = mbd;
// 確保 BeanDefinition 中的 Class 被加載
// 同時在動態(tài)解析類的情況下克隆bean定義提供使用,這個bean定義不能被存儲在mbd中
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 準備當前bean的lookupMethod和replacedMathoed等途戒,可以參考https://www.cnblogs.com/ViviChan/p/4981619.html
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
//拋出異常
......
}
try {
// 使BeanPostProcessors有機會返回一個代理bean
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
//拋出異常
......
}
try {
//doCreateBean才是關鍵惊来,后面會展開
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
//拋出異常
......
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
//拋出異常
......
}
catch (Throwable ex) {
//拋出異常
......
}
}
八、doCreateBean(beanName, mbdToUse, args)
又是一長串代碼棺滞,真的難頂了裁蚁,不過我想spring這么做也是有他的苦衷的,給人家一個面子繼續(xù)看下去吧继准。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// BeanWrrapper枉证,Bean包裝器,簡單理解成對bean賦值的移必,后面展開
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//若mbd為單例室谚,需要先判斷是否為FactoryBean
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
//如果instanceWrapper為空,則創(chuàng)建一個bean實例
if (instanceWrapper == null) {
//createBeanInstance崔泵,創(chuàng)建bean實例封裝到wrapper中秒赤,后面展開
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//通過wrapper獲取到了bean
final Object bean = instanceWrapper.getWrappedInstance();
//處理bean類型
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 允許post-processors修改mbd
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//簡單來說就是對mbd做一些加工
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
//拋出異常
......
}
mbd.postProcessed = true;
}
}
// 解決循環(huán)依賴的問題
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
......
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// bean在實例化后,還需要賦值和初始化(init)
Object exposedObject = bean;
try {
//這一步負責屬性裝配憎瘸,關鍵就在于BeanWrapper
populateBean(beanName, mbd, instanceWrapper);
//處理 bean 初始化完成后的各種回調
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
//拋出異常
......
}
//主要用于解決循環(huán)引用入篮,這部分先跳過吧
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
//拋出異常
......
}
}
}
}
// 注冊bean為使用后即銷毀
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
//拋出異常
......
}
return exposedObject;
}
doCreateBean方法真是細節(jié)拉滿,分別來看看以下關鍵的幾步
1.BeanWrapper
可以發(fā)現createBeanInstance方法雖然創(chuàng)建了bean實例幌甘,但是返回的其實是一個BeanWrapper潮售,他到底是個什么東西?
其實BeanWrapper相當于一個容器锅风,Spring委托BeanWrapperwancehngBean屬性的填充工作酥诽。在Bean實例被創(chuàng)建出來之后,容器主控程序將Bean實例通過BeanWrapper包裝起來皱埠,這是通過調用BeanWrapper的setWrappedInstance方法完成的肮帐。
2.createBeanInstance(beanName, mbd, args)
這里是創(chuàng)建bean實例的關鍵,由于考慮后續(xù)代碼依舊有一大把边器,我的心態(tài)實在受到了影響训枢,就放到下一次討論吧……
3.populateBean(beanName, mbd, instanceWrapper)
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
//若beanwrapper為空,則需要判斷是否需要為bean賦值
if (bw == null) {
//有屬性且wrapper為空饰抒,則會拋出異常肮砾,原因不言而喻
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
//沒有屬性,那就不需要賦值啦袋坑!直接返回
else {
return;
}
}
// 到這步的時候仗处,bean 實例化完成(通過工廠方法或構造方法)眯勾,但是還沒開始屬性設值,InstantiationAwareBeanPostProcessor 的實現類可以在這里對 bean進行狀態(tài)修改
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 如果返回 false婆誓,代表不需要進行后續(xù)的屬性設值吃环,也不需要再經過其他的 BeanPostProcessor 的處理
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
//若不需要再賦值,則return
if (!continueWithPropertyPopulation) {
return;
}
//獲取propertyValues
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
//下面的代碼能知道干了啥就行洋幻,不是(就是)因為我實力不夠郁轻,謝謝
// 通過名字找到所有屬性值,如果是 bean 依賴文留,先初始化依賴的 bean好唯。記錄依賴關系
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 通過類型裝配
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//是否包含InstantiationAwareBeanPostProcessors
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//是否需要深度檢查
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//使用postProcessor對propertyValues進行處理
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
//檢查依賴
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
// 設置 bean 實例的屬性值,這里就不展開了燥翅,到此骑篙,bean實例的賦值就完成了
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
九、結論
寫了這么多森书,bean實例的創(chuàng)建還是要被移到后面了靶端,不過這次的收獲也不小,從refresh加載單例bean其實可以窺見spring是如何加載所有bean的凛膏,其中也包括了一些postProcessor的實際應用等等杨名。由于代碼真的很多,所以覺得還是需要花時間消化消化的猖毫。
希望后續(xù)的代碼能善待我吧台谍,阿門!