Spring框架原理之實例化bean和@Autowired實現原理方式
兩部分流程都較長,如果只對Bean的實例化感興趣只需要看到5.DefaultSingletonBeanRegistry小節(jié)即可,后面是分析@Autowired注解的實現原理。
一、UML類圖及流程分析
1.UML類圖組成
UML類圖組成如下:

這個圖中我們可以大致分為六個部分:
1、第一部分肯定是BeanDefinition的父類和子類組成的,這部分的組成有需要再細分一下,共可以分為六部分:
AttributeAccessor接口:這個接口提供了setAttribute和getAttribute等操作屬性的方法提供給子類實現;BeanMetadataElement接口:該接口只提供了一個getSource方法,提供子類獲取源對象方法;BeanDefinition接口:bean定義的直接接口,這個接口提供了常見的scope、lazy、dependsOn、initMethod和destroyMethod等屬性配置方法,規(guī)范了一個Spring管理的Bean必須實現哪些屬性;AnnotatedBeanDefinition:注解bean定義,里面提供了兩個方法,一個是獲取注解元數據,另一個是獲得方法元數據;BeanDefinitionHolder:該類和子類BeanComponentDefinition的作用便是持有bean的名字、別名和其對應的BeanDefinition,可以注冊為內部bean的占位符;BeanDefinitionBuilder:普通BeanDefinition的構造器,這里面可以構造RootBeanDefinition、ChildBeanDefinition和GenericBeanDefinition等多個類型的bean定義,想要快速實例化一個bean定義可以用此類完成;
2、BeanDefinitionParser接口:從名字便可以看出來其大致作用,用來解析BeanDefinition的接口,其主要是被Spring的NamespaceHandlerSupport實現子類來完成諸如<component-scan/>和<annotation-config/>等XML標簽的讀取解析去獲取Bean定義的;
3、BeanDefinitionRegistry接口:bean定義的注冊中心,該接口的實現子類將可以完成注冊、刪除和獲取bean定義等操作,Spring默認實現的Bean工廠DefaultListableBeanFactory便實現了該接口來管理bean定義;
4、BeanWrapper接口:這部分的接口功能便是封裝一個bean實例,且提供為這個bean調用對應的setter和getter方法,設置bean的具體成員屬性值;
5、@Autowired注解實現相關的類:如圖中的最右側部分的InjectionPoint實現層級和InjectionMetadata相關層級,這部分是存儲實現@Autowired注解功能的必要參數,如class類型和這個class對象所需要的自動注入的對象;而DependencyDescriptor則保存了需要賦值的字段或者方法返回值和賦值的beanClass類型,隨后再根據DependencyDescriptor的具體子類類型判斷返回list、map、array或者單個的bean對象;
6.NamedBeanHolder:用來存儲beanName和已經初始化完成的bean實例,這個對象在參數為class類型調用getBean時被使用。
2.流程分析
Spring工廠實例化bean時對象的變化流程圖:

我在分析該流程時將其分為了三個部分:
- 中間的核心部分:這部分的主要流程是在bean工廠的兩個抽象類AbstractBeanFactory和AbstractAutowireCapableBeanFactory中完成的,主要的功能便是通過bean的名稱調用getBean方法,隨后在這兩個類中完成初始化以及調用此過程中涉及到的接口,其中比較常用的便是FactoryBean和BeanPostProcessor兩個接口,諸如其它的Aware接口也是在這個流程調用的;
- 右邊的封裝部分:雖然這部分調用的getBean也是BeanFactory接口聲明的方法,但我們分析初始化Bean流程時可以把這個部分當成額外的封裝部分,是對通過beanName獲取bean的一種基于便利性的額外封裝實現。這個流程主要是在DefaultListableBeanFactory類中完成的,其大致作用便是通過class類型獲取唯一的候選者beanName,因為一個class類型可能會在工廠中匹配到多個beanName,因此需要做一些額外處理,當獲得beanName之后再調用核心部分去實例化bean;
- 左邊的功能拓展部分:這部分的入口是在獲取到BeanWrapper之后,調用BeanPostProcessor實現類AutowiredAnnotationBeanPostProcessor來完成的。這部分的功能便是處理@Autowired注解,先通過BeanWrapper獲取bean的class對象,再判斷其字段和方法有哪些是被這個注解的,隨后再依次處理判斷,在獲得自動注入的這些實例時,將再次調用getBean,形成一個遞歸調用,完成bean的獲取和賦值到字段或方法上。
二、源碼分析
1.DefaultListableBeanFactory類實例化bean部分
先從外部額外封裝的getBean方法分析起,其關鍵源碼部分如下:
public class DefaultListableBeanFactory
extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry,
Serializable {
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
// 對外單個類參數獲取bean,將會調用后面帶有參數args的方法
return getBean(requiredType, (Object[]) null);
}
@Override
public <T> T getBean(Class<T> requiredType, @Nullable Object... args)
throws BeansException {
// 調用resolveBean方法解析bean
Object resolved = resolveBean(ResolvableType
.forRawClass(requiredType), args, false);
// 如果返回的是nll,則代表Spring工廠中沒有class類型的bean信息
if (resolved == null) {
throw new NoSuchBeanDefinitionException(requiredType);
}
return (T) resolved;
}
@Nullable
private <T> T resolveBean(ResolvableType requiredType,
@Nullable Object[] args, boolean nonUniqueAsNull) {
// 流程圖中右側的最后一步,將resolveNamedBean方法返回的NamedBeanHolder
// 類型判空,如果不為空則直接將內部的beanInstance實例返回,在
// resolveNamedBean方法中執(zhí)行的是第三步,把ResolvableType轉為beanName
NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args,
nonUniqueAsNull);
if (namedBean != null) {
return namedBean.getBeanInstance();
}
// 如果從當前的beanFactory中獲取不到bean的信息則從父類beanFactory中
// 獲取,依次遞歸下去,這里可以忽略這段代碼(正常情況下沒有層級關系)
...
return null;
}
@Nullable
private <T> NamedBeanHolder<T> resolveNamedBean(
ResolvableType requiredType, @Nullable Object[] args,
boolean nonUniqueAsNull) throws BeansException {
// 根據requiredType中的class類型獲取beanName集合,這里面將會判斷l(xiāng)ist
// 集合beanDefinitionNames來獲取普通的bean候選者,判斷set集合
// manualSingletonNames中手動添加的單例對象,兩者都會判斷FactoryBean和
// 普通的bean對象,并選舉出來稱為候選者,具體流程不分析
String[] candidateNames = getBeanNamesForType(requiredType);
// 如果獲取到的beanName是多個,則說明這一個class對應多個bean
if (candidateNames.length > 1) {
List<String> autowireCandidates =
new ArrayList<>(candidateNames.length);
// 先判斷beanDefinitionMap集合中是否含有該candidateName
// 如果有則后續(xù)進行轉換到candidateNames數組
for (String beanName : candidateNames) {
if (!containsBeanDefinition(beanName) ||
getBeanDefinition(beanName).isAutowireCandidate()) {
autowireCandidates.add(beanName);
}
}
// 將List轉換為原來的String[]數組
if (!autowireCandidates.isEmpty()) {
candidateNames = StringUtils
.toStringArray(autowireCandidates);
}
}
// 如果candidateNames數組長度為1,則說明class只有一個對應的bean
if (candidateNames.length == 1) {
String beanName = candidateNames[0];
// 直接獲取0號位置的beanName,并調用getBean(beanName)方法初始化bean
// 隨后將bean實例賦值到NamedBeanHolder中的beanInstance屬性中
// 以便該方法返回后直接返回beanInstance屬性對象
return new NamedBeanHolder<>(beanName, (T) getBean(beanName,
requiredType.toClass(), args));
}
else if (candidateNames.length > 1) {
Map<String, Object> candidates =
new LinkedHashMap<>(candidateNames.length);
// 對candidateNames進行依次處理
for (String beanName : candidateNames) {
// 如果是單例對象,即singletonObjects中含有此bean
if (containsSingleton(beanName) && args == null) {
// 直接先調用getBean(beanName)獲取bean實例
Object beanInstance = getBean(beanName);
// 雖然放入到candidates集合中,以便后續(xù)返回具體的bean
candidates.put(beanName, (beanInstance instanceof NullBean?
null : beanInstance));
}
else {
// 如果是原型的,則先把class類型放到candidates中,后續(xù)返回時再
// 實例化返回
candidates.put(beanName, getType(beanName));
}
}
// 獲取主要的候選者,即最終的bean返回對象,即聲明對象時是否使用
// @Primary注解了,如果注解了則使用其中最后一個候選者
String candidateName = determinePrimaryCandidate(candidates,
requiredType.toClass());
// 如果判斷的主要候選者為空(沒有一個bean被@Primary注解)
if (candidateName == null) {
// 根據OrderComparator優(yōu)先級獲取優(yōu)先級最高的bean
candidateName = determineHighestPriorityCandidate(candidates,
requiredType.toClass());
}
// 如果不為空
if (candidateName != null) {
// 從前面組裝的candidates集合Map中獲取對應的bean對象
// 這里獲取到的可能是bean實例化對象,也有可能是class對象
Object beanInstance = candidates.get(candidateName);
// 如果beanInstance是空或者類型是class
if (beanInstance == null || beanInstance instanceof Class) {
// 調用getBean(candidateName)方法實例化bean
beanInstance = getBean(candidateName,
requiredType.toClass(), args);
}
// 使用NamedBeanHolder封裝bean實例并返回
return new NamedBeanHolder<>(candidateName, (T)beanInstance);
}
// 前面?zhèn)魅氲膎onUniqueAsNull值是false,因此如果到這里candidateName
// 還是為null,則拋出異常沒有唯一的bean可返回
if (!nonUniqueAsNull) {
throw new NoUniqueBeanDefinitionException(requiredType,
candidates.keySet());
}
}
// 如果候選者candidateNames為0,則直接返回null
return null;
}
}這個類中主要方法棧為四層,調用這四個方法棧將會調用到其它的類中,如調用完之后將會返回已經實例化的bean對象,在調用方法棧中將會調用到AbstractBeanFactory類中的getBean方法中。也就是說DefaultListableBeanFactory類只是對getBean(class)這個方法進行了一層額外的封裝,最終還是調用到了AbstractBeanFactory類中,因此我自己把這部分流程劃為額外封裝實現。
2.AbstractBeanFactory抽象類
前面說過,調用getBean(class)最終實例化bean時將會調用到這個類中,且這個類是核心部分的入口,可以說是非常重要了。接下來我們看下其部分關鍵源碼:
public abstract class AbstractBeanFactory
extends FactoryBeanRegistrySupport
implements ConfigurableBeanFactory {
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
@Override
public <T> T getBean(String name, Class<T> requiredType)
throws BeansException {
return doGetBean(name, requiredType, null, false);
}
@Override
public Object getBean(String name, Object... args)
throws BeansException {
// 這三個方法都是調用了doGetBean,唯一的不同便在于傳入的參數不一樣
// 但是name這個參數是必須的
return doGetBean(name, null, args, false);
}
protected <T> T doGetBean(final String name,
@Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly)
throws BeansException {
// 或許這個方法看起來會很長,但實際上可以把其分為五個功能大點
// 一、使用aliasMap集合將傳入的name轉變成beanName
final String beanName = transformedBeanName(name);
Object bean;
// 二、先從singletonObjects單例緩存集合中獲取bean對象,如果不為空
// 則直接返回賦值給sharedInstance對象如果為空則從singletonFactories集合
// 中獲取單例工廠類,并調用getObject獲取單例bean對象返回賦值
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 如果sharedInstance不為空,則調用getObjectForBeanInstance方法
// 判斷其是否被FactoryBean封裝的,如果是則調用該接口的getObject方法
// 獲取bean對象,如果不是則直接返回,其具體的方法流程略過,主要是
// 判斷FactoryBean接口的,有興趣的可以去看下,后面都會用到
bean = getObjectForBeanInstance(sharedInstance, name, beanName,
null);
} else {
// 判斷該beanName是否是原型且正在被創(chuàng)建的,如果是則拋出異常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 三、判斷該beanFactory的父類工廠是否含有該bean對象,此略過,最終
// 還是會跑到該方法的后續(xù)流程
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null &&
!containsBeanDefinition(beanName)) {
...
}
// typeCheckOnly傳入的是false,因此會進入判斷
if (!typeCheckOnly) {
// 該方法的作用便是將beanName添加到alreadyCreated集合中,標記為
// 已經實例化過beanName對應的bean對象
markBeanAsCreated(beanName);
}
// 該try-catch塊將是實例化bean的地方,前面只是判斷
try {
// 從mergedBeanDefinitions集合中獲取具體的BeanDefinition對象
final RootBeanDefinition mbd =
getMergedLocalBeanDefinition(beanName);
// 判斷該bean定義是否合乎標準,如非抽象類
checkMergedBeanDefinition(mbd, beanName, args);
// 四、處理@DependsOn注解中的bean對象,在這里將會先實例化注解中
// 引用的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 如果獲取的dependsOn不為空則依次遍歷其中引入的值
for (String dep : dependsOn) {
// 判斷是否是循環(huán)依賴,如果是則拋出異常,所謂循環(huán)依賴則是
// @Bean注解的A方法使用@DependsOn依賴了@Bean注解的B方法
// 但是B方法又使用了@DependsOn依賴了A方法,形成死循環(huán)
if (isDependent(beanName, dep)) {
throw new BeanCreationException();
}
// 跑到這里代表前面并沒有死循環(huán)依賴的發(fā)生,則把彼此相關的
// 依賴關系放入到dependentBeanMap中,因此第一次是絕對會
// 執(zhí)行到這里的
registerDependentBean(dep, beanName);
try {
// 實例化依賴的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException();
}
}
}
// 五、判斷Bean是單例或是原型進行相應的實例化操作
if (mbd.isSingleton()) {
// 如果是單例,則使用lambda實例化一個ObjectFactory對象傳入
// getSingleton方法實例化單例,這個方法也很重要,后續(xù)會分析
sharedInstance = getSingleton(beanName, () -> {
try {
// 實例化的ObjectFactory對象執(zhí)行的方法也很簡單
// 單純的調用createBean方法創(chuàng)造bean對象
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// 如果創(chuàng)造失敗則銷毀對象(清除緩存)
destroySingleton(beanName);
throw ex;
}
});
// 判斷這個bean是否被FactoryBean封裝
bean = getObjectForBeanInstance(sharedInstance, name,
beanName, mbd);
} else if (mbd.isPrototype()) {
// 如果bean是原型
Object prototypeInstance = null;
try {
// 記錄原型bean正在被創(chuàng)建,在前面會進行判斷
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 執(zhí)行完后將當前創(chuàng)建的原型bean標記去除
afterPrototypeCreation(beanName);
}
// 判斷這個bean是否被FactoryBean封裝
bean = getObjectForBeanInstance(prototypeInstance, name,
beanName, mbd);
} else {
// 如果是其它類型的scope參數
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
// scope屬性不能為空
if (scope == null) {
throw new IllegalStateException();
}
try {
// Scope接口是Spring提供給外部使用的,因此如果指定了
// 自定義的Scope實現,調用里面的get方法將會執(zhí)行普通的
// 原型bean流程,只是開發(fā)者可以在Scope中對該bean進行
// 額外的處理判斷
Object scopedInstance = scope.get(beanName, () -> {
// 實際上ObjectFactory對象的操作流程和原型bean一模一樣
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
// 判斷這個bean是否被FactoryBean封裝
bean = getObjectForBeanInstance(scopedInstance, name,
beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException();
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 這部分是判斷如果要求的類型requiredType和獲得的bean類型不一致進行
// 轉換的地方,正常使用是不會出現這種情況的,因此暫時略過
if (requiredType != null && !requiredType.isInstance(bean)) {
...
}
// 返回bean對象
return (T) bean;
}
}實際上doGetBean這個方法流程可以分為五個部分流程,如下圖:

3.AbstractAutowireCapableBeanFactory抽象類
我們從上面的AbstractBeanFactory類已經分析到了createBean方法了,由于創(chuàng)建和初始化bean的核心流程都在AbstractAutowireCapableBeanFactory類的幾個方法中,因此這個類的流程會比較多,大致流程可以看到下面的流程圖:

接下來我們看下其關鍵部分源碼:
public abstract class AbstractAutowireCapableBeanFactory
extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
public <T> T createBean(Class<T> beanClass) throws BeansException {
// AbstractBeanFactory并沒有調用這個方法,但是我們也可以看下
// 這個方法流程就是將beanClass封裝成Bean定義且設置成原型
RootBeanDefinition bd = new RootBeanDefinition(beanClass);
bd.setScope(SCOPE_PROTOTYPE);
bd.allowCaching = ClassUtils.isCacheSafe(beanClass,
getBeanClassLoader());
return (T) createBean(beanClass.getName(), bd, null);
}
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd,
@Nullable Object[] args)
throws BeanCreationException {
// 真正創(chuàng)造bean的方法,這個方法大致可以分為三個部分
RootBeanDefinition mbdToUse = mbd;
// 一、將beanName和bean定義解析成對應的class類型
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() &&
mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
// 確定具體的beanClass類型
mbdToUse.setBeanClass(resolvedClass);
}
// 準備方法覆蓋,無關緊要
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException();
}
// 二、如果bean定義的beforeInstantiationResolved屬性為true
// 則直接使用BeanPostProcessor對bean進行處理,且處理后直接返回
// 不再使用Spring工廠的實例化流程,意味著Spring很多實例化中途的接口
// 都將不起作用,還沒見到過這種實例化方式的。這里面將會調用
// InstantiationAwareBeanPostProcessor接口的before方法,調用
// BeanPostProcessor接口的after方法
try {
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException();
}
try {
// 三、調用doCreateBean方法實行真正創(chuàng)建bean流程
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
} catch (BeanCreationException |
ImplicitlyAppearedSingletonException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException();
}
}
protected Object doCreateBean(final String beanName,
final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 根據createBean方法的流程來看,其相當于是外面再封裝了一層,用來解析
// beanClass屬性和提前使用BeanPostProcessor完成bean的實例化,真正的
// Spring實例化bean的流程其實是在這個方法中
// 在這個方法中共可以分為五個部分
BeanWrapper instanceWrapper = null;
// 一、如果是單例對象,則把factoryBeanInstanceCache緩存清掉,同時獲取
// 緩存的BeanWrapper實例對象,單例對象(FactoryBean)在調用getType等
// 方法時將會被實例化后放到factoryBeanInstanceCache中,一般流程為null
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 如果instanceWrapper為null,則調用createBeanInstance實例化對象
// 在執(zhí)行完這個方法后bean對象才會被實例化
if (instanceWrapper == null) {
// 具體實例化對象的地方,其大部分會調用instantiateBean方法利用反射來
// 完成bean的實例化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 分別獲取實例化對象和class類型
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 二、允許程序在創(chuàng)建bean對象后再修改合并后的bean定義
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 里面會調用MergedBeanDefinitionPostProcessor的實現類
// 其也是BeanPostProcessor的一個子接口
applyMergedBeanDefinitionPostProcessors(mbd, beanType,
beanName);
}
catch (Throwable ex) {
throw new BeanCreationException();
}
mbd.postProcessed = true;
}
}
// 三、快速緩存單例即使被BeanFactoryAware這樣的生命周期接口觸發(fā)
// 以便能夠解決循環(huán)引用,前提是該單例bean正在創(chuàng)建中
boolean earlySingletonExposure = (mbd.isSingleton() &&
this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 將bean緩存到singletonObjects等單例集合中
// 大部分單例類都會調用到這里面,以便完成復雜的循環(huán)引用,當所有的
// 實例被后續(xù)的流程初始化后,最終的單例將變成最終的形態(tài)
addSingletonFactory(beanName, () ->
getEarlyBeanReference(beanName, mbd, bean));
}
Object exposedObject = bean;
// 四、對bean進行bean定義屬性填充及執(zhí)行一系列Spring初始化接口
try {
// 構造bean,這里面將會處理@Autowired和@Resource等操作bean成員屬性
// 的注解,也會分別調用setter方法去設置對應的值,等下會分析
populateBean(beanName, mbd, instanceWrapper);
// initializeBean方法將會執(zhí)行工廠接口的回調,如aware系列接口、
// InitializingBean接口、initMethod和BeanPostProcessor的接口調用
// 這里調用BeanPostProcessor是真正的調用其接口after和before方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
} catch (Throwable ex) {
if (ex instanceof BeanCreationException &&
beanName.equals(((BeanCreationException) ex)
.getBeanName())) {
throw (BeanCreationException) ex;
} else {
throw new BeanCreationException();
}
}
// 五、判斷單例對象是否造成了兩次實例化導致單例對象出現不一致的現象
// 如果前面的提前存儲單例對象成立,則進入(一般來說會進入)
if (earlySingletonExposure) {
// 再次獲得提前放入的bean對象
Object earlySingletonReference = getSingleton(beanName, false);
// 如果提前放入的bean對象引入不為空
if (earlySingletonReference != null) {
// 如果經過populateBean和initializeBean方法后bean引用沒變
// 則把早期的bean對象賦值給exposedObject對象
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping &&
hasDependentBean(beanName)) {
// 如果經過兩個初始化方法bean引用變了,則說明其它的bean已經
// 通過這兩個方法實例化成功了單例bean,且兩個單例bean不一致
// 拋出異常
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans =
new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(
dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException();
}
}
}
}
try {
// 注冊需要銷毀的bean對象:實現了DisposableBean和AutoCloseable接口
// 或者指明了destroy方法
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException();
}
// 返回暴露的bean對象
return exposedObject;
}
protected void populateBean(String beanName, RootBeanDefinition mbd,
@Nullable BeanWrapper bw) {
// 這個方法共可以分為四個部分
// 該方法的主要作用便是使用bean定義屬性值為BeanWrapper中的對象
// 填充對應的值
if (bw == null) {
// 如果bean定義為空且屬性值不為空則拋出異常,否則直接跳過該方法
if (mbd.hasPropertyValues()) {
throw new BeanCreationException();
} else {
return;
}
}
// 一、根據InstantiationAwareBeanPostProcessor接口的
// postProcessAfterInstantiation方法返回值判斷是否
// 繼續(xù)執(zhí)行填充bean對象屬性
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() &&
hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp =
(InstantiationAwareBeanPostProcessor) bp;
// 根據其接口方法返回值判斷要不要繼續(xù)執(zhí)行后面的填充流程
if (!ibp.postProcessAfterInstantiation(bw
.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 為false則直接跳過
if (!continueWithPropertyPopulation) {
return;
}
// 獲取bean定義中的屬性值
PropertyValues pvs = (mbd.hasPropertyValues() ?
mbd.getPropertyValues() : null);
// 二、判斷bean的自動注入模式為AUTOWIRE_BY_NAME或AUTOWIRE_BY_TYPE
// 一般都是使用默認的后續(xù)流程,只有特殊指定才會進入這兩步,這兩個
// 方法的作用便是把當前的bean定義根據參數名字或者類型從bean工廠中
// 獲取對應的bean,并且保存到newPvs對象中,如mybatis的mapper便是
// 使用type類型獲取到sqlSessionTemplate和sqlSessionFactory兩個bean的
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 根據autotowire的名稱(如適用)添加屬性值
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 根據自動裝配的類型(如果適用)添加屬性值
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 判斷是否有InstantiationAwareBeanPostProcessor接口,有為true
boolean hasInstAwareBpps =
hasInstantiationAwareBeanPostProcessors();
// 是否需要檢查依賴,一般而言此值默認為false,暫時忽略
boolean needsDepCheck = (mbd.getDependencyCheck() !=
AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
// 三、如果有InstantiationAwareBeanPostProcessor接口則進入
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
// 依次獲取InstantiationAwareBeanPostProcessor接口調用其
// postProcessProperties方法和postProcessPropertyValues方法
// 并獲得這兩個方法的返回值,以便后續(xù)使用
// 解析@Autowired注解并賦值便是在段方法中完成的,后面會分析
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp =
(InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs,
bw.getWrappedInstance(), beanName);
// 此方法流程已被官方刪除,原來的流程實際調用的也是
// postProcessProperties,因此這一段可以忽略
if (pvsToUse == null) {
...
}
pvs = pvsToUse;
}
}
}
// 略過
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw,
mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
// 四、如果返回的pvs不為空,則說明這些屬性需要設置到BeanWrapper中
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
protected Object initializeBean(final String beanName,
final Object bean, @Nullable RootBeanDefinition mbd) {
// 這個方法共可以分為四個部分
// 一、調用invokeAwareMethods方法,從名字就可以看出來,這個方法是用來
// 調用Aware系列接口,包括BeanNameAware、BeanClassLoaderAware和
// BeanFactoryAware,System.getSecurityManager()語句只是為了判斷當前
// 系統(tǒng)有沒有權限調用Aware接口
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
// 二、調用BeanPostProcessor接口的postProcessBeforeInitialization方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean =
applyBeanPostProcessorsBeforeInitialization(wrappedBean,
beanName);
}
try {
// 三、這里面會調用InitializingBean接口的afterPropertiesSet方法
// 且會調用指定的initMethod和destroyMethod方法
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException();
}
// 四、調用BeanPostProcessor接口的postProcessAfterInitialization方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean =
applyBeanPostProcessorsAfterInitialization(wrappedBean,
beanName);
}
// 返回經過Aware、init、destroy、BeanPostProcessor接口的before和after
// 系列接口方法處理過的bean對象
return wrappedBean;
}
}想要理清楚這里面的流程,還是需要自己親自走一遍創(chuàng)建的源碼流程,否則不管看多少次流程分析到頭來也還是會生疏忘記。
4.DefaultSingletonBeanRegistry類
這個類主要負責單例對象的緩存和一些判斷。接下來看下其部分關鍵源碼:
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry
implements SingletonBeanRegistry {
// 保存單例對象的Map集合
private final Map<String, Object> singletonObjects =
new ConcurrentHashMap<>(256);
// 保存單例對象和其對應的ObjectFactory集合
private final Map<String, ObjectFactory<?>> singletonFactories =
new HashMap<>(16);
// 提前緩存單例的集合
private final Map<String, Object> earlySingletonObjects =
new HashMap<>(16);
// 正在創(chuàng)建單例的集合
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
// 注冊成功的單例bean對象
private final Set<String> registeredSingletons =
new LinkedHashSet<>(256);
@Override
@Nullable
public Object getSingleton(String beanName) {
// 在前面創(chuàng)建bean的流程中調用的便是這個方法
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName,
boolean allowEarlyReference) {
// 這個方法實際上只是從緩存中獲取單例對象
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null &&
isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 進入到這里說明緩存對象沒有命中
singletonObject = this.earlySingletonObjects.get(beanName);
// 再判斷提前緩存的單例對象集合能不能命中
if (singletonObject == null && allowEarlyReference) {
// 如果提前緩存的單例對象也無法命中則從singletonFactories
// 集合中查找對應的ObjectFactory對象,如果不為空則調用其
// getObject初始化bean對象
ObjectFactory<?> singletonFactory = this
.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 調用getObject初始化單例bean對象,并緩存起來
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName,
singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
protected void addSingleton(String beanName, Object singletonObject) {
// 添加單例說明這個單例對象已經完全初始化完成,因此可以把提前緩存在
// earlySingletonObjects和singletonFactories集合的bean刪除,直接放進
// singletonObjects和registeredSingletons集合
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
public Object getSingleton(String beanName,
ObjectFactory<?> singletonFactory) {
// 這個方法在前面初始化單例bean時會被調用,且singletonFactory對象
// 是由lambda實例化的一個對象,里面只有一個調用createBean方法語句
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
// 先判斷單例bean緩存有沒有這個bean,如果有就直接返回,沒有則進入判斷
if (singletonObject == null) {
// 該單例bean有另外一個線程正在初始化中拋出異常
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException();
}
// 記錄單例beanName正在實例化中
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions =
(this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 調用getObject方法(實際為調用createBean方法,因為這個
// 對象方法中只有調用createBean方法語句)
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;
}
// 標記beanName已經創(chuàng)建完成
afterSingletonCreation(beanName);
}
// 如果創(chuàng)建過程中為拋出異常則添加到單例緩存中
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
// 返回單例對象
return singletonObject;
}
}
}5.AutowiredAnnotationBeanPostProcessor類
這個類是BeanPostProcessor接口的實現類,是完成@Autowired注解原理的地方,接下來看到其關鍵源碼:
public class AutowiredAnnotationBeanPostProcessor
extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered,
BeanFactoryAware {
// 這個集合中保存了@Autowired和@Value注解
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes =
new LinkedHashSet<>(4);
@Override
public PropertyValues postProcessProperties(PropertyValues pvs,
Object bean, String beanName) {
// 找到這個bean哪些字段和方法需要自動注入
InjectionMetadata metadata = findAutowiringMetadata(beanName,
bean.getClass(), pvs);
try {
// 調用注入流程
metadata.inject(bean, beanName, pvs);
} catch (BeanCreationException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException();
}
return pvs;
}
private InjectionMetadata findAutowiringMetadata(String beanName,
Class<?> clazz, @Nullable PropertyValues pvs) {
// 返回到類名作為緩存鍵,以便向后兼容自定義調用者。
String cacheKey = (StringUtils.hasLength(beanName) ?
beanName : clazz.getName());
// 首先對并發(fā)映射進行快速檢查,使用最小的鎖定。
InjectionMetadata metadata = this
.injectionMetadataCache.get(cacheKey);
// 先進行一層緩存判斷,但是不上鎖,可以讓一大批線程通過這個判斷方法
// 完成是否需要刷新的判斷,而不需要阻塞線程
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
// 進行第二次判斷,此時判斷的對象是需要刷新的,且并發(fā)量高只有幾個
// 線程會同時到這里,保證了最小粒度線程判斷,這種使用方法和單例對
// 象的兩重判斷原理一樣,都是為了避免同一個class執(zhí)行多次if塊里面
// 的流程
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
// 根據類獲取需要自動注入的字段和方法
metadata = buildAutowiringMetadata(clazz);
// 放入緩存
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
private InjectionMetadata buildAutowiringMetadata(
final Class<?> clazz) {
// 看起來這個方法很長,但實際上只執(zhí)行了兩個有用的邏輯
List<InjectionMetadata.InjectedElement> elements =
new ArrayList<>();
Class<?> targetClass = clazz;
do {
// 當前類所需要自動注入的元素集合
final List<InjectionMetadata.InjectedElement> currElements =
new ArrayList<>();
// 依次遍歷字段判斷哪些字段擁有autowiredAnnotationTypes集合中的注解
// 如果有的話則將其封裝添加到currElements集合中
ReflectionUtils.doWithLocalFields(targetClass, field -> {
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
return;
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field,
required));
}
});
// 類似遍歷字段的,這里只是遍歷了方法,其它流程一樣
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver
.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method,
bridgedMethod)) {
return;
}
AnnotationAttributes ann =
findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils
.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
return;
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils
.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method,
required, pd));
}
});
// 添加到需要返回的集合elements中
elements.addAll(0, currElements);
// 再遍歷父類,依次循環(huán)
targetClass = targetClass.getSuperclass();
} while (targetClass != null && targetClass != Object.class);
// 封裝成注入元數據類型
return new InjectionMetadata(clazz, elements);
}
}可以看到這個類執(zhí)行的操作只是獲取該bean被@Autowired和@Value注解的字段和方法,然后使用InjectedElement和InjectionMetadata對象封裝。
6.InjectionMetadata類
從上面的流程我們知道了會調用到這個類的inject方法中來,接下來我們看下其部分關鍵源碼:
public class InjectionMetadata {
// 需要注入的bean class類型
private final Class<?> targetClass;
// 該bean class需要注入的字段和方法集合
private final Collection<InjectedElement> injectedElements;
public void inject(Object target, @Nullable String beanName,
@Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements :
this.injectedElements);
// 如果需要注入的字段和方法集合迭代器不為空
if (!elementsToIterate.isEmpty()) {
// 依次循環(huán)調用元素的inject方法,
for (InjectedElement element : elementsToIterate) {
element.inject(target, beanName, pvs);
}
}
}
}7.AutowiredFieldElement內部類
這個類是InjectionMetadata.InjectedElement內部類的子類實現,主要針對的是需要自動注入字段的執(zhí)行,需要注意的是這個類也是AutowiredAnnotationBeanPostProcessor的內部類實現。接下來我們看其關鍵源碼部分:
private class AutowiredFieldElement
extends InjectionMetadata.InjectedElement {
@Override
protected void inject(Object bean, @Nullable String beanName,
@Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
// 先判斷是否已經被緩存了
if (this.cached) {
// 如果緩存了就直接從bean工廠中獲取或直接返回cachedFieldValue的值
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
// 沒有緩存則將字段封裝成DependencyDescriptor對象
DependencyDescriptor desc = new DependencyDescriptor(field,
this.required);
// 設置對應的bean類型
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 直接調用bean工廠的resolveDependency方法解析這個bean涉及的
// 依賴bean,并且最終返回bean值
value = beanFactory.resolveDependency(desc, beanName,
autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName,
new InjectionPoint(field), ex);
}
synchronized (this) {
// 如果未緩存,則說明是第一次
if (!this.cached) {
// 如果返回的值不為空
if (value != null || this.required) {
this.cachedFieldValue = desc;
// 注冊這個bean和自動注入值的依賴關系
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
// 如果返回值只有一個,則封裝成對象類型
// ShortcutDependencyDescriptor緩存起來
String autowiredBeanName = autowiredBeanNames
.iterator().next();
// 從bean工廠中判斷確實這個value返回值存在且類型正確
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName,
field.getType())) {
// 緩存起來
this.cachedFieldValue =
new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
} else {
this.cachedFieldValue = null;
}
// 設置為緩存狀態(tài)
this.cached = true;
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
// 利用映射把獲得的value值set到字段上
field.set(bean, value);
}
}
}這個類的作用便是緩存且調用bean工廠獲取需要注入的bean值,然后set到相應的字段或者方法上。
8.DefaultListableBeanFactory類處理@Autowired注解
我們可以先分析一下處理自動注入依賴的方法流程圖:

直入主題,其關鍵部分源碼如下:
public class DefaultListableBeanFactory
extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry,
Serializable {
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor,
@Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames,
@Nullable TypeConverter typeConverter) throws BeansException {
// 這個方法也是一個中間方法,前面兩個判斷不用管,只需要看到最后一個即可
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
} else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor,
requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()){
return new Jsr330Factory().createDependencyProvider(descriptor,
requestingBeanName);
} else {
// 正常流程直接看到這一步來即可,調用返回的result一般情況下為null
Object result = getAutowireCandidateResolver()
.getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// 因此一般情況下會調用這個方法獲取bean對象,這個方法也是需要重點
// 分析的
result = doResolveDependency(descriptor, requestingBeanName,
autowiredBeanNames, typeConverter);
}
return result;
}
}
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor,
@Nullable String beanName,
@Nullable Set<String> autowiredBeanNames,
@Nullable TypeConverter typeConverter) throws BeansException {
// 像前面介紹的流程一樣,將DependencyDescriptor對象轉換為InjectionPoint
// 這個方法也很長,需要慢慢分析,大致可以分為六個部分
InjectionPoint previousInjectionPoint =
ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
// 一、如果是ShortcutDependencyDescriptor類型的則會直接調用getBean
// 方法,但是一般都是DependencyDescriptor類型,大部分情況可忽略
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
// 二、從descriptor對象的注解中嘗試獲取值,只有當方法返回的類型是
// QualifierAnnotationAutowireCandidateResolver才會這樣做,默認的
// 是ContextAnnotationAutowireCandidateResolver類型,此流程可忽略
Class<?> type = descriptor.getDependencyType();
Object value = getAutowireCandidateResolver()
.getSuggestedValue(descriptor);
if (value != null) {
// 如果獲得的值是String類型,則需要使用使用Expression語法獲取值
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null &&
containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
// 實際會調用Expression語法獲取值
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ?
typeConverter : getTypeConverter());
try {
// 對返回的值進行類型轉換
return converter.convertIfNecessary(value, type,
descriptor.getTypeDescriptor());
} catch (UnsupportedOperationException ex) {
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type,
descriptor.getField()) :
converter.convertIfNecessary(value, type,
descriptor.getMethodParameter()));
}
}
// 三、解決自動注入的值為數組、Map集合或者Collection集合,如果是
// 數組則直接把bean工廠中這個類型的按照Comparator排序返回;如果是
// Collection集合且類型為接口則獲取對應的bean對象且進行類型轉換和
// 排序處理;如果是Map則直接key為beanName,value為這個類型的對象;
// 這幾個類型descriptor對象將被封裝成MultiElementDescriptor類型
// 這個類型后續(xù)將會調用bean工廠的getBean方法,獲取集合需要的bean對象
// 這里實際會調用到findAutowireCandidates方法中,只是中間解析了上面
// 所說的三種集合類型,findAutowireCandidates這個方法等下分析
Object multipleBeans = resolveMultipleBeans(descriptor,
beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 四、直接調用findAutowireCandidates方法獲取Map集合key為beanName
// Object為bean對象
Map<String, Object> matchingBeans =
findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
// 如果為空且required為true,則檢查beanDefinitionNames中
// 是否有該類型的bean,如果沒有則拋出異常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type,
descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
// 五、處理獲取到的候選matchingBeans集合,分為單個和多個,數量為0
// 的情況以前面已經處理了
if (matchingBeans.size() > 1) {
// 如果候選有多個,則使用Comparator獲取最高優(yōu)先級的候選者
// 或者beanName一模一樣的bean對象
autowiredBeanName = determineAutowireCandidate(matchingBeans,
descriptor);
if (autowiredBeanName == null) {
// 如果候選者為空且required為true,則檢查并拋出異常
if (isRequired(descriptor) ||
!indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor
.getResolvableType(), matchingBeans);
} else {
// required為false則直接返回null
return null;
}
}
// 獲取候選者
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// 僅有一個,直接獲取第一個的key和值
Map.Entry<String, Object> entry =
matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
// 六、對獲取到的單個候選者進行處理
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
// 如果從候選者們獲取到的的類型是class,則需要調用resolveCandidate
// 方法來通過class類型實例化bean,resolveCandidate方法會直接調用
// bean工廠的getBean方法;如果不是class類型,那一定是實例化好的
// bean對象
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor
.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
// 進行required參數的判斷,不滿足拋異常
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type,
descriptor.getResolvableType(), descriptor);
}
result = null;
}
// 判斷獲取的類型和值是否一樣,不一樣則拋出異常
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName,
type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(
previousInjectionPoint);
}
}
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType,
DependencyDescriptor descriptor) {
// 在獲取到beanName和這個bean的class類型后將會調用這個方法來獲取
// 這個class類型的一系列候選者,該方法一共可以分為三個部分
// 一、或者這個beanName的候選者名稱
String[] candidateNames = BeanFactoryUtils
.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result =
new LinkedHashMap<>(candidateNames.length);
// 一、判斷resolvableDependencies集合中類型相同的對象
// 遍歷判斷已經解析過的依賴對象,如果類型相同或者是需要實例化的父類
// 則將其添加到result中
for (Map.Entry<Class<?>, Object> classObjectEntry :
this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = classObjectEntry.getKey();
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
autowiringValue = AutowireUtils
.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue),
autowiringValue);
break;
}
}
}
// 二、對前一步獲取到的對象和候選者名稱進行遍歷處理,處理后的結果將會添加
// 到result中addCandidateEntry方法后面會分析
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) &&
isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor,
requiredType);
}
}
// 三、如果需要返回的候選者結果集為空,正常情況下前面獲取到的result為空
// 這個方法塊中獲取到的result也為空,但是其具體作用場景尚不清楚
// 因此暫時略過
if (result.isEmpty()) {
// 如果第一輪沒有找到任何內容,考慮回退匹配對應的名稱對象
boolean multiple = indicatesMultipleBeans(requiredType);
...
}
return result;
}
private void addCandidateEntry(Map<String, Object> candidates,
String candidateName,
DependencyDescriptor descriptor, Class<?> requiredType) {
// 解決不同的descriptor對象
if (descriptor instanceof MultiElementDescriptor) {
// MultiElementDescriptor類型則直接調用bean工廠的getBean方法獲取
// 處理化bean對象
Object beanInstance = descriptor.resolveCandidate(candidateName,
requiredType, this);
if (!(beanInstance instanceof NullBean)) {
candidates.put(candidateName, beanInstance);
}
} else if (containsSingleton(candidateName) ||
(descriptor instanceof StreamDependencyDescriptor &&
((StreamDependencyDescriptor) descriptor).isOrdered())) {
// 如果是單例或者是StreamDependencyDescriptor類型,也是調用
// bean工廠的getBean方法獲取處理化bean對象,只是value可能為NullBean
Object beanInstance = descriptor.resolveCandidate(candidateName,
requiredType, this);
candidates.put(candidateName, (beanInstance instanceof NullBean ?
null : beanInstance));
} else {
// 無法識別處理的則將String名字編程對象的class對象,以方便后續(xù)流程
// 直接初始化class類型對應的bean對象
candidates.put(candidateName, getType(candidateName));
}
}
}至此,兩個流程的分析便已經結束了,要想了解其具體流程還是需要自己去走一遍源碼,并且仔細分析一下各個方法的搭配和前后流程關系,否則不管看多少遍都是無用功。
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Spring Boot項目如何同時支持HTTP和HTTPS協議的實現
這篇文章主要介紹了Spring Boot項目如何同時支持HTTP和HTTPS協議的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-10-10
BigDecimal divide除法除不盡報錯的問題及解決
這篇文章主要介紹了BigDecimal divide除法除不盡報錯的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06
Springboot JPA 枚舉Enum類型存入到數據庫的操作
這篇文章主要介紹了Springboot JPA 枚舉Enum類型存入到數據庫的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01

