上一節(jié)分析了Spring從緩存中獲取單例bean的過程瘾敢,相對于創(chuàng)建一個(gè)全新的單例bean葫盼,該過程還是很簡單的,本節(jié)接著分析創(chuàng)建單例bean的準(zhǔn)備工作。
引
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly)
throws BeansException {
// 1徐矩、轉(zhuǎn)換bean的名稱,去掉&前綴,且如果bean有別名的話,優(yōu)先使用別名
final String beanName = transformedBeanName(name);
Object bean;
// 2、從緩存中獲取bean
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 3叁幢、如果未能從緩存中獲取到bean,則要重新創(chuàng)建bean
else {
// Fail if we're already creating this bean instance: We're assumably within a circular reference.
// 3.1判斷指定的原型模式的bean是否當(dāng)前正在創(chuàng)建(在當(dāng)前線程內(nèi)),如果是->則拋出異常(Spring不會解決原型模式bean的循環(huán)依賴)
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 3.2 檢測bean definition是否存在beanFactory中
BeanFactory parentBeanFactory = getParentBeanFactory();
// 如果當(dāng)前BeanFactory中不包含給定beanName的beanDefinition定義,且父beanFactory不為空,則去父beanFactory中再次查找
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 3.3 將name轉(zhuǎn)換為原始beanName
// 因?yàn)檫@里的name已經(jīng)經(jīng)過beanName的規(guī)范處理,例如:&myBean-->規(guī)范-->myBean
// 所以當(dāng)我們再次去父beanFactory查找時(shí),要將beanName再次轉(zhuǎn)換為原始的beanName,myBean-->回轉(zhuǎn)-->&myBean
String nameToLookup = originalBeanName(name);
// 3.4 下面會遞歸調(diào)用各種getBean的方法重載,從當(dāng)前bean的父factoryBean中加載bean
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// 參數(shù)不為空,則委托parentBeanFactory使用顯式參數(shù)調(diào)動
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// 參數(shù)為空,則委托parentBeanFactory使用標(biāo)準(zhǔn)的getBean方法獲取bean
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
// 否則委托parentBeanFactory使用默認(rèn)的getBean方法
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// 3.3 如果當(dāng)前bean不是用于類型檢查,則將該bean標(biāo)記為已經(jīng)被創(chuàng)建或者即將被創(chuàng)建
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 3.4 合并beanDefinition,如果指定的bean是一個(gè)子bean的話,則遍歷其所有的父bean
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 校驗(yàn)合并的beanDefinition,如果驗(yàn)證失敗,則拋出異常
checkMergedBeanDefinition(mbd, beanName, args);
// 3.5 確保初始化當(dāng)前bean所依賴的bean滤灯。
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 循環(huán)所有的依賴bean,并遞歸實(shí)例化
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注冊依賴
registerDependentBean(dep, beanName);
try {
// 實(shí)例化依賴的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 3.6 創(chuàng)建單例bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 創(chuàng)建bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 創(chuàng)建原型模式bean
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
在到達(dá)步驟3.6之前的工作,都是為創(chuàng)建當(dāng)前單例bean的準(zhǔn)備工作曼玩。其中包括了:對BeanDefinition的檢測鳞骤、如果當(dāng)前BeanFactory中不包含BeanDefinition則對父BeanFactory的檢測、BeanDefinition的合并黍判、依賴bean的初始化等等工作豫尽。
1.創(chuàng)建單例bean
// 3.6 創(chuàng)建單例bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 創(chuàng)建bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
- getSingleton方法分析
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
// 1、嘗試從緩存中獲取bean
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
// 2顷帖、創(chuàng)建bean之前的回調(diào)方法
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 3美旧、通過getObject創(chuàng)建bean的實(shí)例
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
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;
}
// 4、創(chuàng)建bean之后的回調(diào)方法
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 5贬墩、將新創(chuàng)建的單例bean加入緩存
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
該方法中完成了對單例bean的創(chuàng)建工作榴嗅,并在創(chuàng)建bean之前和之后進(jìn)行方法回調(diào)進(jìn)行一些異常信息的檢查,最后將單例bean加入緩存中震糖。其中關(guān)鍵的步驟就是第三步
通過getObject創(chuàng)建bean的實(shí)例录肯,singletonObject = singletonFactory.getObject();
,這里初學(xué)者閱讀起來可能稍微有些繞吊说,singletonFactory.getObject();方法執(zhí)行后會回到3.6中的return createBean(beanName, mbd, args)论咏;完成對bean的創(chuàng)建。
- createBean方法分析
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 確保此時(shí)bean類已經(jīng)被解析颁井,并且在動態(tài)解析類不能存儲在共享合并bean定義中時(shí)克隆bean定義厅贪。
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 準(zhǔn)備和驗(yàn)證配置的方法注入
// 注意:這里處理的是replace-method和lookup-method方法注入,而不是@Override注解
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 讓beanPostprocessor有機(jī)會返回一個(gè)代理而不是目標(biāo)bean實(shí)例。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "beanPostProcessor before instantiation of bean failed", ex);
}
try {
// 執(zhí)行bean創(chuàng)建,并返回bean的實(shí)例
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
從方法名上好像已經(jīng)接觸到了IoC的核心-->bean的創(chuàng)建雅宾,但是很遺憾养涮,該方法中依然只是例行檢查工作,真正的創(chuàng)建方法在doCreateBean中眉抬,從這里也能看出spring代碼閱讀的一個(gè)小技巧贯吓,真正干活兒的往往是doXXX開頭的方法,而在doXXX之前都是做一些準(zhǔn)備工作蜀变。