spring源碼:bean的創建
從doGetBean()方法中可以知道,bean會根據不同的scope進行bean創建,但真實創建bean實例的是createBean()方法。下面我們就跟蹤一下這個方法:
createBean()源碼
AbstractAutowireCapableBeanFactory.java
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 確定並加載bean的class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 準備覆蓋的方法
try {
mbdToUse.prepareMethodOverrides();
}
catch ...
try {
// 給 Bean Post 處理器一個機會來返回代理而不是目標 Bean 實例。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
//應用初始化前的後處理器,如果處理器中返回了AOP的代理對象,則直接返回該單例對象,不需要繼續創建
if (bean != null) {
return bean;
}
}
catch ....
try {
//創建bean對象
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch ...
catch ...
}
}
上面代碼對應步驟爲:
- 根據設置的class屬性或者根據className來解析到class
- 對override屬性進行標記和驗證(bean XML配置中的lookup-method和replace-method屬性)
- 應用初始化前的後處理器,如果處理器中返回了AOP的代理對象,則直接返回該單例對象,不需要繼續創建
- 創建bean
從上面知道創建bean的代碼被封裝在doCreateBean()中。
doCreateBean()源碼
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 1. 先從factoryBeanInstanceCache緩存中嘗試獲取
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 2. 如果緩存中不存在,則根據bean對應的策略創建新的實例,如:工廠方法、構造器自動注入、簡單初始化
if (instanceWrapper == null) {
// ------------bean的實例化-------------------
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 3. 應用MergedBeanDefinitionPostProcessor 後處理器,合併bean的定義信息
// Autowire等註解信息就是在這一步完成預解析,並且將註解需要的信息放入緩存
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch ...
mbd.postProcessed = true;
}
}
// 4. 依賴處理
// 是否需要提前曝光 = 單例&允許循環依賴&bean正在創建中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//爲了避免循環依賴,在bean初始化完成前,就將創建bean實例的ObjectFactory放入工廠緩存(singletonFactories)
// AOP就是在這裏將advice動態織入到bean中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 5. 對bean屬性進行填充,注入bean中的屬性,會遞歸初始化依賴的bean
Object exposedObject = bean;
try {
// ----------- 填充屬性 --------
populateBean(beanName, mbd, instanceWrapper);
// --------------bean的初始化------------------
//調用初始化方法,比如init-method、注入Aware對象、應用後處理器
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch ....
// 6. 循環依賴檢查
if (earlySingletonExposure) {
//從提前曝光的bean緩存中查詢bean,目的是驗證是否有循環依賴存在
//如果存在循環依賴,也就是說該bean已經被其他bean遞歸加載過,放入了提早曝光的bean緩存中
Object earlySingletonReference = getSingleton(beanName, false);
//只有檢測到循環依賴的情況下,earlySingletonReference纔不會爲null
if (earlySingletonReference != null) {
//如果exposedObject沒有在 initializeBean 初始化方法中改變,也就是沒有被增強
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);
}
}
//因爲bean創建後,其依賴的bean一定也是已經創建的
//如果actualDependentBeans不爲空,則表示依賴的bean並沒有被創建完,即存在循環依賴
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,...);
}
}
}
}
// 7. 註冊DisposableBean,對應xml中的 destroy-method,以便的銷燬時調用
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch ...
return exposedObject;
}
以上方法的步驟爲:
- 如果是單例則首先清除緩存
- 實例化bean,並使用BeanWarpper包裝
- 如果存在工廠方法,則使用工廠方法實例化
- 如果有多個構造函數,則根據傳入的參數確定構造函數進行初始化
- 使用默認的構造函數初始化
- 應用MergedBeanDefinitionPostProcessor,Autowired註解就是在這樣完成的解析工作
- 依賴處理。如果A和B存在循環依賴,那麼Spring在創建B的時候,需要自動注入A時,並不會直接創建再次創建A,而是通過放入緩存中A的ObjectFactory來創建實例,這樣就解決了循環依賴的問題
- 屬性填充。所有需要的屬性都在這一步注入到bean
- 循環依賴檢查
- 註冊DisposableBean。如果配置了destroy-method,這裏需要註冊,以便在銷燬時調用
- 完成創建並返回
從上面的步驟可以知道bean的創建主要是三步:- bean的實例化
- 實例化後bean屬性的填充
- bean的初始化
下面我們一個一個進行解析
1.bean的實例化
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 獲取bean class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果工廠方法不爲空(RootBeanDefinition中存在factoryMethodNam屬性,或者配置文件中配置了factory-method),則使用工廠方法初始化策略
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
//如果一個類有多個構造函數,每個構造函數都有不同的參數,所以調用前需要先根據參數鎖定構造函數或對應的工廠方法
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
//如果已經解析過則使用解析好的構造函數方法不需要再次鎖定
if (resolved) {
if (autowireNecessary) {
//構造函數自動注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
//使用默認構造函數構造
return instantiateBean(beanName, mbd);
}
}
// 根據參數解析構造函數
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//構造函數自動注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// 使用默認構造函數
return instantiateBean(beanName, mbd);
}
從上面的代碼發現實例化bean的方式就三種:
- 如果存在工廠方法,則使用工廠方法實例化
- 如果有多個構造函數,則根據傳入的參數確定構造函數進行初始化
- 使用默認的構造函數初始化
主要涉及的方法:
instantiateUsingFactoryMethod()、autowireConstructor()、instantiateBean()
autowireConstructor()方法
ConstructorResolver.java
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
/**
* 1. 構造參數的確定
* 1.1 調用getBean方法時傳入
* 1.2 緩存中獲取
* 1.3 配置文件中獲取
*/
//explicitArgs通過getBean方法傳入
//如果getBean方法調用的時候指定方法參數那麼直接使用
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
//如果getBean方法沒有傳入參數,則嘗試從配置文件中解析
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// 從緩存中獲取
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
//配置的構造函數參數
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
// 解析參數類型,如構造函數A(int,int)通過此方法後就會把配置中的("1","1")轉換成(1,1)
//緩存中的值可能是原始值也可能是最終值
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
//沒有被緩存
if (constructorToUse == null) {
// 需要解析構造函數。
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
//配置文件中配置的構造函數參數
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
//用於承載解析後的參數值
resolvedValues = new ConstructorArgumentValues();
//能解析到的參數個數
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
/**
* 2. 構造函數的確定
*
*/
// Take specified constructors, if any.
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch ...
}
//構造函數排序,public構造函數優先參數數量降序、非public構造函數參數數量降序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
for (Constructor<?> candidate : candidates) {
Class<?>[] paramTypes = candidate.getParameterTypes();
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
// 如果已經找到選用的構造參數,而且傳入的參數個數大於當前的構造參數個數則終止,因爲構造函數已經按照參數個數降序排列
break;
}
if (paramTypes.length < minNrOfArgs) {
//參數個數不相等
continue;
}
ArgumentsHolder argsHolder;
if (resolvedValues != null) {
try {
//有參數,則根據參數類型和參數名構造對象
//註釋上獲取參數名稱
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
//參數名稱探測器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
//獲取構造參數名稱
paramNames = pnd.getParameterNames(candidate);
}
}
///根據名稱和數據類型創建參數持有者
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring);
}
catch...
}
else {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
//構造函數沒有參數
argsHolder = new ArgumentsHolder(explicitArgs);
}
//檢查是否有不確定性的構造函數存在,例如不同構造函數的參數爲父子關係
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// 如果它代表着當前最接近的匹配則選擇作爲構造函數
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,..);
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,..);
}
if (explicitArgs == null) {
//將解析的構造函數加入緩存
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
try {
//使用策略的instantiate方法,實例化bean
final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
Object beanInstance;
if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
beanFactory.getAccessControlContext());
}
else {
beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
//將構造的實例加入BeanWrapper中
bw.setBeanInstance(beanInstance);
return bw;
}
catch ...
}
此方法的主要邏輯爲:
- 構造參數的確定
- 構造函數的確定
- 根據構造函數轉換傳入參數的類型
- 構造函數不確定性的驗證
- 根據實例化策略及確定的構造函數和參數實例化bean.
instantiateBean()無參構造
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
//實例化
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
從上面得知,不過是自動注入的,還是默認無參的構造函數都是調用實例化策略的instantiate()方法實例化bean的,那下面就去看看這個方法
instantiate()真正實現實例化
SimpleInstantiationStrategy.java
// 如果有需要覆蓋或動態替換的方法,則使用cglib進行動態代理(因爲可以在創建代理的同時將動態方法織入到類中)
//但如果沒有需要動態改變的方法,爲了方便直接使用反射
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch ...
}
}
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// 使用了replace或者lookup的配置方法
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
通過SimpleInstantiationStrategy策略的instantiate()真正實現實例化了bean.
2.populateBean()填充屬性
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// 給InstantiationAwareBeanPostProcessors最後一次機會在屬性注入前修改Bean的屬性值
// 1.具體通過調用postProcessAfterInstantiation方法,如果調用返回false,表示不必繼續進行依賴注入,直接返回
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//判斷是否繼續填充 bean
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
//如果後處理器發出停止填充命令則終止後續的執行
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 根據Bean配置的依賴注入方式完成注入,默認是0,即不走以下邏輯,所有的依賴注入都需要在xml文件中有顯式的配置
// 如果設置了相關的依賴裝配方式,會遍歷Bean中的屬性,根據類型或名稱來完成相應注入,無需額外配置
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
// 深拷貝當前已有的配置
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 根據名稱進行注入
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 根據類型進行注入
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
// 結合注入後的配置,覆蓋當前配置
pvs = newPvs;
}
//3.後處理器是否已經初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//是否需要循環依賴檢查
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.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;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
// 檢查是否滿足相關依賴關係,對應的depends-on屬性,需要確保所有依賴的Bean先完成初始化
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
// 4.將pvs上所有的屬性填充到BeanWrapper對應的Bean實例中,注意到這一步,TestBean的student屬性還是RuntimeBeanReference,即還未解析實際的Student實例
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
此方法的代碼步驟:
- 執行InstantiationAwareBeanPostProcessors處理器的postProcessAfterInstantiation()方法,控制程序是否繼續進行屬性填充。
- 根據注入類型(byName\byType),提取依賴的bean,並統一存入PropertyValues中。
- 執行InstantiationAwareBeanPostProcessors處理器的postProcessPropertyValues()方法,在獲取屬性完成 填充屬性前 對屬性的再次處理。
- 將所有的PropertyValues中的屬性填充至BeanWrapper中。
這裏有三個關鍵函數autowireByName、autowireByType、applyPropertyValues,下面就這個三個函數展開。
autowireByName()
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 根據bw的PropertyDescriptors,遍歷出所有可寫的(即set方法存在),存在於BeanDefinition裏的PropertyValues,且不是簡單屬性的屬性名
// 簡單屬性的判定參照下面方法,主要涵蓋基本類型及其包裝類,Number,Date等
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
// 遞歸初始化相關Bean
Object bean = getBean(propertyName);
// 根據名稱添加到pvs中
pvs.add(propertyName, bean);
// 註冊依賴關係
registerDependentBean(propertyName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
autowireByType()
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 獲取類型轉換器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
// 類似的,過濾出滿足裝配條件的Bean屬性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
//如果是Object類型不進行裝配
if (Object.class != pd.getPropertyType()) {
// 獲取相關的setter方法參數
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// // 定義是否允許懶加載。
boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
// 這裏會根據傳入desc裏的入參類型,作爲依賴裝配的類型
// 再根據這個類型在BeanFacoty中查找所有類或其父類相同的BeanName
// 最後根據BeanName獲取或初始化相應的類,然後將所有滿足條件的BeanName填充到autowiredBeanNames中。
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
// 註冊依賴
registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
applyPropertyValues()
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
//如果mpvs中的值已經被轉換爲對應的類型那麼可以直接設置到beanwapper中
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
//如果pvs並不是使用MutablePropertyValues封裝的類型,那麼直接使用原始的屬性獲取方法
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//獲取對應的解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
//遍歷屬性,將屬性轉換爲對應類的對應屬性的類型
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
3. bean的初始化
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//對特殊的bean處理:Aware、BeanClassLoaderAware、BeanFactoryAware
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//應用後處理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
///激活用戶自定義的init方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//應用後處理器
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}