IOC容器概述
如果合作對象的的引用或依賴關系的管理由具體對象來完成,會導緻代碼的高度耦合和可測試行的降低。這些依賴關系可以通過把對象的依賴注入交給IOC容器來完成,解耦代碼的同時提高代碼的可測試性。
如果對面向對象系統的中的對象進行簡單分類,會發現一部分是資料對象外,其他很大一部分對象是用來處理資料的,這些對象并不常發生變化,是系統中基礎的部分(如Service類)。在很多情況下,這些對象以單例的形式起作用就可以滿足應用的需求。同時,這些對象之間的互相依賴關系也是比較穩定的,一般不會随着應用的運作狀态的改變而改變。這些特性使得這些對象非常适合由IOC容器來管理。
Spring IOC 容器已經是一個産品實作,對多種應用場景作了适配。在IOC容器的設計中,可以看到兩個主要的容器息列,一個是BeanFactory接口的簡單容器系列,隻實作了容器的最基本功能;另一個是ApplicationContext應用上下文,作為容器的進階形态,在簡單容器的基礎上,增加了許多面向架構的特性:
- 支援不同的資訊源。繼承MessageSource,這些資訊源的擴充功能可以支援國際化的實作,為開發多語言版本的應用提供服務;
- 通路資源。AbstractApplicationContext繼承DefaultResourceLoader,使用者可以靈活地定義Bean資訊,然後使用者程式可從不同的I/O途徑得到Bean定義資訊;
- 支援應用事件。繼承ApplicationEventPublisher,進而在上下文中引入了事件機制。這些事件和Bean生命周期的結合為Bean管理提供了便利。
1、Spring IOC的初始化過程
-
BeanDefinition的定位
Spring使用ResourceLoader的Resource接口來完成BeanDefinition的定位。
要根據Spring定義的規則提供Bean定義,例如XML、注解(@Service、@Component、 @Repository、@Controller)、Java 配置(@Configuration配合@Bean)。
-
BeanDefinition載入和注冊
載入的工作由BeanDefinitionReader來完成(Bean定義資訊的讀取、解析),載入之後會調用registerBeanDefinition()注冊到beanDefinitionMap。
-
IOC容器初始化
初始化入口:Refresh函數。主要工作:
- 初始化上下文中的消息源
- 初始化上下文中的事件機制
- 預執行個體化單例Bean
- 注冊Bean的後置處理器
-
Bean依賴注入
在第一次向IOC容器請求Bean時,IOC容器對相關的Bean依賴關系進行注入。如果需要提前注入,可以通過lazy-init屬性進行預執行個體化。在依賴注入以後,Bean就可用了。
1.1 BeanDefinition的定位
本文跟蹤的是AnnotationConfigApplicationContext的過程,下面以程式設計的方式使用AnnotationConfigApplicationContext:
AnnotationConfigApplicationContext會先調用無參構造函數,接着調用scan函數掃描包路徑下的包含Component注解的類(@Configuration、@Service等注解都包含該注解),轉化成BeanDefinition并注冊到beanDefinitionMap
/**
* 參數為basePackages的構造函數,觸發IOC容器初始化
*/
public AnnotationConfigApplicationContext(String... basePackages) {
// 調用無參構造函數
this();
// 掃描包路徑下的Bean定義資訊,并載入到beanDefinitionMap
scan(basePackages);
// IOC容器初始化
refresh();
}
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public void scan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
this.scanner.scan(basePackages);
}
public int scan(String... basePackages) {
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
// 掃描包路徑下的包含Component注解的類,轉化成BeanDefinition并注冊到beanDefinitionMap
doScan(basePackages);
// Register annotation config processors, if necessary.
if (this.includeAnnotationConfig) {
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
// BeanDefinition讀取、解析,找到所有包含Component注解的類,轉化成BeanDefinition
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
// 注冊到beanDefinitionMap
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
LinkedHashSet candidates = new LinkedHashSet();
try {
String packageSearchPath = "classpath*:" + this.resolveBasePackage(basePackage) + '/' + this.resourcePattern;
// basePackage類路徑下的Resource定位
Resource[] resources = this.getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = this.logger.isTraceEnabled();
boolean debugEnabled = this.logger.isDebugEnabled();
Resource[] var7 = resources;
int var8 = resources.length;
for(int var9 = 0; var9 < var8; ++var9) {
// Resource定位
Resource resource = var7[var9];
if (traceEnabled) {
this.logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
MetadataReader metadataReader = this.getMetadataReaderFactory().getMetadataReader(resource);
if (this.isCandidateComponent(metadataReader)) {
// BeanDefinition讀取、解析
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
// 判斷是否包含Component注解
if (this.isCandidateComponent((AnnotatedBeanDefinition)sbd)) {
if (debugEnabled) {
this.logger.debug("Identified candidate component class: " + resource);
}
// 包含Component注解的類,添加到candidates
candidates.add(sbd);
} else if (debugEnabled) {
this.logger.debug("Ignored because not a concrete top-level class: " + resource);
}
} else if (traceEnabled) {
this.logger.trace("Ignored because not matching any filter: " + resource);
}
} catch (Throwable var13) {
throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, var13);
}
} else if (traceEnabled) {
this.logger.trace("Ignored because not readable: " + resource);
}
}
return candidates;
} catch (IOException var14) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", var14);
}
}
- @Configuration、@Service等包含@Component注解的BeanDefinition的定位、解析、載入和注冊是在org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan,在Refresh()函數前。
- @Bean注解的BeanDefinition的載入入口是在refresh()函數裡的invokeBeanFactoryPostProcessors(),具體方法是在org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod
1.2 IOC容器的初始化
主要處理以下内容:
- 初始化上下文中的消息源
- 初始化上下文中的事件機制
- 預執行個體化單例Bean
- 注冊Bean的後置處理器
org.springframework.context.support.AbstractApplicationContext#refresh
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 準備工作
prepareRefresh();
// 擷取BeanFactory,包含載入Bean定義資訊()
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 為容器配置ClassLoader、PropertyEditor、BeanPostProcessor等
prepareBeanFactory(beanFactory);
try {
// 設定BeanFactory的後置處理
postProcessBeanFactory(beanFactory);
// 調用BeanFactory的後置處理器,在Bean建立過程中調用
invokeBeanFactoryPostProcessors(beanFactory);
// 注冊Bean的後置處理器
registerBeanPostProcessors(beanFactory);
// 初始化上下文中的消息源
initMessageSource();
// 初始化上下文中的事件機制
initApplicationEventMulticaster();
// 初始化其他的特殊Bean
onRefresh();
// 檢查監聽Bean并注冊
registerListeners();
// 預執行個體化所有的單例(非延遲加載)
finishBeanFactoryInitialization(beanFactory);
// 釋出容器事件,結束refresh
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 銷毀Bean
destroyBeans();
// 重置 'active' 标志
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
} finally {
// 重置緩存
resetCommonCaches();
}
}
}
1.3 依賴注入
在第一次向IOC容器請求Bean時,IOC容器對相關的Bean依賴關系進行注入。如果需要提前注入,可以通過lazy-init屬性進行預執行個體化。在依賴注入以後,Bean就可用了。
預執行個體化入口在org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
this.getBean(weaverAwareName);
}
beanFactory.setTempClassLoader((ClassLoader)null);
beanFactory.freezeConfiguration();
// 預執行個體化類型為單例的Bean
beanFactory.preInstantiateSingletons();
}
/**
* 預執行個體化類型為單例的Bean
*/
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Pre-instantiating singletons in " + this);
}
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();
while(true) {
String beanName;
Object bean;
do {
while(true) {
RootBeanDefinition bd;
do {
do {
do {
if (!var2.hasNext()) {
var2 = beanNames.iterator();
while(var2.hasNext()) {
beanName = (String)var2.next();
// 根據bean名稱擷取單例Bean,
Object singletonInstance = this.getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, this.getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
return;
}
beanName = (String)var2.next();
bd = this.getMergedLocalBeanDefinition(beanName);
} while(bd.isAbstract());
} while(!bd.isSingleton());
} while(bd.isLazyInit());
if (this.isFactoryBean(beanName)) {
bean = this.getBean("&" + beanName);
break;
}
// 調用getBean觸發執行個體化(若Bean還未初始化),
this.getBean(beanName);
}
} while(!(bean instanceof FactoryBean));
FactoryBean<?> factory = (FactoryBean)bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
SmartFactoryBean var10000 = (SmartFactoryBean)factory;
((SmartFactoryBean)factory).getClass();
isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}
if (isEagerInit) {
this.getBean(beanName);
}
}
}
依賴注入的入口為getBean(),getBean()會接着調用doGetBean()
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
String beanName = this.transformedBeanName(name);
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if (sharedInstance != null && args == null) {
if (this.logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
return parentBeanFactory.getBean(nameToLookup);
}
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
try {
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
// 擷取目前Bean的所有依賴Bean
String[] dependsOn = mbd.getDependsOn();
String[] var11;
if (dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length;
for(int var13 = 0; var13 < var12; ++var13) {
String dep = var11[var13];
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
this.registerDependentBean(dep, beanName);
try {
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var24) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
}
}
}
// 建立類型為單例的Bean
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
// 建立類型為原型的Bean執行個體
} else if (mbd.isPrototype()) {
var11 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
Scope 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, () -> {
this.beforePrototypeCreation(beanName);
Object var4;
try {
var4 = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
return var4;
});
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var23) {
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", var23);
}
}
} catch (BeansException var26) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var26;
}
}
// bean類型檢查,最後傳回包含了依賴關系的Bean
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
} else {
return convertedBean;
}
} catch (TypeMismatchException var25) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// Bean執行個體化,這裡會使用政策模式,org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate
// 政策1:使用BeanUtils.instantiateClass;政策2:使用2使用CGLIB(常用的位元組碼生成器的類庫),Enhancer.create方法
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
}
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
// 這裡是對bean進行初始化
Object exposedObject = bean;
try {
this.populateBean(beanName, mbd, instanceWrapper);
// 初始化完成
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}
if (earlySingletonExposure) {
Object earlySingletonReference = this.getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
String[] dependentBeans = this.getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;
int var13 = dependentBeans.length;
for(int var14 = 0; var14 < var13; ++var14) {
String dependentBean = var12[var14];
if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
try {
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
}
/**
* 屬性填充
*/
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 {
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var4 = this.getBeanPostProcessors().iterator();
while(var4.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var4.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
// 擷取RootBeanDefinition的屬性
PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
// 開始依賴注入的過程
if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
if (resolvedAutowireMode == 1) {
// 根據Bean的名稱依賴注入
this.autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == 2) {
// 根據Bean的類型依賴注入
this.autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = mbd.getDependencyCheck() != 0;
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
Iterator var9 = this.getBeanPostProcessors().iterator();
while(var9.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var9.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
}
if (pvs != null) {
// 對屬性進行依賴注入
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (!pvs.isEmpty()) {
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl)bw).setSecurityContext(this.getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues)pvs;
if (mpvs.isConverted()) {
try {
bw.setPropertyValues(mpvs);
return;
} catch (BeansException var18) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var18);
}
}
original = mpvs.getPropertyValueList();
} else {
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = this.getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
// 使用BeanDefinitionValueResolver對BeanDefinition進行解析
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, (TypeConverter)converter);
List<PropertyValue> deepCopy = new ArrayList(original.size());
boolean resolveNecessary = false;
Iterator var11 = original.iterator();
while(true) {
while(var11.hasNext()) {
PropertyValue pv = (PropertyValue)var11.next();
if (pv.isConverted()) {
deepCopy.add(pv);
} else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
// 解析屬性
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = this.convertForProperty(resolvedValue, propertyName, bw, (TypeConverter)converter);
}
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();
}
try {
// 調用BeanWrapper.setPropertyValues()進行屬性填充
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
return;
} catch (BeansException var19) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var19);
}
}
}
}
1.4 BeanPostProcessors後置處理器的實作
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
this.invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 前置處理,觸發postProcessorsBeforeInitialization的回調
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
try {
// 調用Bean的初始化方法
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
if (mbd == null || !mbd.isSynthetic()) {
// 後置處理,觸發postProcessorsAfterInitialization的回調
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
1.5 單例類型的Bean執行個體循環依賴的解決關鍵
/**
* 這裡是解決循環依賴的關鍵,allowEarlyReference預設值為true,意味着預設支援單例類型Bean的循環依賴
* 循環依賴是用三級緩存來解決的, Bean執行個體建立後放入三級緩存,下次擷取該Bean從三級緩存中擷取,并移動到二級緩存,
*/
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 一級緩存中擷取,一級緩存用于存放完全初始化好(填充屬性後)的 bean,從該緩存中取出的 bean 可以直接使用
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
synchronized(this.singletonObjects) {
// 二級緩存中擷取,二級緩存用于存放提前曝光的單例,存放原始的 bean 對象(尚未填充屬性),用于解決循環依賴
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 三級緩存中擷取, 三級緩存用于存放 剛建立的bean單例,用于解決循環依賴
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 三級緩存擷取成功,則移動到二級緩存
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}