目錄
1、getSingleton
2、createBean
1)、擷取真正的Class類型
2)、初始化真正使用的RootBeanDefinition
3)、lookup-method和replace-method的處理
4)、InstantiationAwareBeanPostProcessor處理(resolveBeforeInstantiation)
5)、doCreateBean(真正的建立)
繼續AbstractBeanFactory的doGetBean分析,主要分析是5、6步驟:
1、判斷是否正在建立中
2、判斷父BeanFactory是否存在(一般都不存在,是以不分析了)
3、調用getMergedLocalBeanDefinition方法擷取BeanDefinition,并且調用checkMergedBeanDefinition方法驗證
4、擷取BeanDefinition#getDependsOn,有依賴則周遊,遞歸調用getBean
5、根據BeanDefinition的scope按照單利、原型。其他類型進行初始化(目前隻考慮單利類型)
6、過調用的是getBean(A.class)類型,則需要進行轉換
單利類型的初始化過程如下:
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
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,再getObjectForBeanInstance,因為目前不知道需要擷取的是FactoryBean本身,還是FactoryBean#getObject,還是正常的Bean。主要的方法依賴于createBean初始化之後,getSingleton根據情況傳回。
1、getSingleton
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
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!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
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;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
在createBean完成後,會調用DefaultSingletonBeanRegistry的getSingleton方法傳回Bean對象。
1、在createBean調用完後new 了Bean的抽象工廠,還是用synchronized鎖住singletonObjects,當然第一次擷取到的還是null
2、判斷是否正在建立中
3、beforeSingletonCreation做一些判斷
4、核心方法是singletonFactory.getObject();擷取到單利的Bean
5、afterSingletonCreation做一些判斷
6、調用addSingleton方法放入緩存中下次就能直接擷取了(這裡鎖了兩次singletonObjects對象)
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
2、createBean
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 省略try catch的代碼部分,友善清晰的看過程
RootBeanDefinition mbdToUse = mbd;
// 擷取真正的Class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 對Spring定義的lookup-method和replace-method的處理
mbdToUse.prepareMethodOverrides();
// 初始化前的InstantiationAwareBeanPostProcessor處理器(可能在這裡傳回對象)
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
// 在InstantiationAwareBeanPostProcessor沒有擷取到對象,則走正常建立過程(這才是真正的初始化過程)
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
1)、擷取真正的Class類型
protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName,
final Class<?>... typesToMatch) throws CannotLoadBeanClassException {
// 省略try catch部分的代碼
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->
doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
}
else {
return doResolveBeanClass(mbd, typesToMatch);
}
}
很多時候RootBeanDefinition沒有設定beanClass,則需要解析對應的Class(設定了直接傳回)。後面分析該過程。
2)、初始化真正使用的RootBeanDefinition
上面解析的Class如果不為null,則需要初始化一個RootBeanDefinition,并将該Class設定進去,否則就使用傳入的RootBeanDefinition即可。
3)、lookup-method和replace-method的處理
對lookup-method和replace-method類型的标記處理而已
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
if (hasMethodOverrides()) {
getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}
protected void prepareMethodOverride(MethodOverride mo)
throws BeanDefinitionValidationException {
int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
if (count == 0) {
throw new BeanDefinitionValidationException("省略");
} else if (count == 1) {
// Mark override as not overloaded, to avoid the overhead of arg type checking.
mo.setOverloaded(false);
}
}
4)、InstantiationAwareBeanPostProcessor處理(resolveBeforeInstantiation)
在真正的doCreateBean之前允許InstantiationAwareBeanPostProcessor類型的BeanPostProcess,調用postProcessBeforeInstantiation方法。也可以了解,Spring不僅允許FactoryBean的getObject類型初始化Bean,還允許InstantiationAwareBeanPostProcessor傳回Bean。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
applyBeanPostProcessorsBeforeInstantiation方法如下:
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
如果InstantiationAwareBeanPostProcessor處理(傳回)過該Class類型的Bean,那麼該Bean就沒有走正常bean的生命周期(詳細可以參見:Spring-Bean的作用域和生命周期),那麼允許其調用一次BeanPostProcess的後置處理方法postProcessAfterInitialization,前置處理方法是修改Bean資訊的,是以這裡沒必要回調前置方法了。就拿到所有的BeanPostProcess周遊回調即可,如下:
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean,
String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
5)、doCreateBean(真正的建立)
完整的Bean的生命周期都會在這裡完成,也是最複雜的過程。next專門進行分析。