接著上文器瘪,來看下DefaultListableBeanFactory
的getBean
過程翠储。
BeanFactory
有幾個getBean
的重載方法。但在DefaultListableBeanFactory
中橡疼,這些重載方法最終會調用AbstractBeanFactory
類的一個doGetBean
方法援所。
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
@Override
public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
追蹤doGetBean方法
下面的縮減的代碼
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
//從緩存中獲取單例
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}else {
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 創(chuàng)建單例的bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}else if (mbd.isPrototype()) {
// 創(chuàng)建原型的bean
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}else{
//其他類型
}
}catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
return (T) bean;
}
從上面代碼可以看出spring在getBean
的時候主要做了兩個操作:
- 從緩存中獲取Bean對象
- 若緩存中不存在Bean對象,則執(zhí)行創(chuàng)建bean的操作
為了弄清流程欣除,我們還是先弄懂spring單例的創(chuàng)建過程住拭。
spring單例的創(chuàng)建過程
從上面的代碼可以抽取一下創(chuàng)建單例的代碼。
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
從上面可以看出历帚,創(chuàng)建單例的時候主要是調用了getSingleton
的方法滔岳,該方法第一個參數是beanName,第二個參數是一個ObjectFactory
挽牢,從名字上就可以看出來谱煤,ObjectFactory
主要是用來創(chuàng)建對象的。而這個ObjectFactory
主要也是調用AbstractAutowireCapableBeanFactory
的createBean
方法禽拔。createBean
把beanName
刘离、RootBeanDefinition
、arg
傳輸進去睹栖。好硫惕,先看看getSingleton
的代碼
getSingleton方法
getSingleton
方法是AbstractBeanFactory
的父類DefaultSingletonBeanRegistry
中的方法。DefaultSingletonBeanRegistry
從名字可以看出主要是為了單例而創(chuàng)建的野来。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) { //加鎖
//從緩存中獲取對象
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
//緩存中獲取不到對象恼除,則開始創(chuàng)建對象
//判斷容器是否在銷毀,若是在銷毀曼氛,則直接跑一次豁辉。
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,"");
}
//創(chuàng)建前校驗,主要是檢查排除的bean和把beanName放到singletonsCurrentlyInCreation的map中去
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
//通過ObjectFactory去創(chuàng)建Object
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;
}
//創(chuàng)建后主要檢查排除的bean和把beanName從singletonsCurrentlyInCreation的map中移除
afterSingletonCreation(beanName);
}
if (newSingleton) {
//如果是創(chuàng)建則把生成的對象添加到緩存中去
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
從上面代碼中可以看出搪锣,getSingleton
方法主要任務是確保并發(fā)秋忙,確保只創(chuàng)建一個單例,而且具體創(chuàng)建對象還是交給ObjectFactory
創(chuàng)建构舟,等對象創(chuàng)建完成后,緩存對象。
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);
}
}
上面是緩存對象的方法狗超,主要也是把對象放到singletonObjects
和registeredSingleton
兩個Map中去弹澎。
再回頭看看createBean
方法。
createBean
追蹤下AbstractAutowireCapableBeanFactory
的createBean
方法
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
//準備prepare方法
//主要是處理的lookup-method努咐、replace-method方法苦蒿,若找到相應的的方法,則進行標記
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.
//嗯渗稍,上面描述很明確了佩迟,給機會BeanPostProcessors去返回一個代理類,如果不返回代理類則繼續(xù)
//BeanPostProcessors是只實現InstantiationAwareBeanPostProcessor接口的類竿屹,實現接口的類可以自定義生成自己的bean
Object bean = resolveBeforeInstantiation(beanName, mbdToUse); //標記1??
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//嗯报强,這里就開始真正創(chuàng)建類了
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(),
beanName, "Unexpected exception during bean creation", ex);
}
}
跟蹤下標記1??中的方法,看看里面到底是怎么回事
resolveBeforeInstantiation
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
和applyBeanPostProcessorsAfterInitialization
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;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
原來是給機會BeanPostProcessor
和它的子接口InstantiationAwareBeanPostProcessor
的機會拱燃,也就是說我們實現這兩個接口的bean就可以處理自己的對象生成規(guī)則了秉溉,666的。
好了碗誉,在深究下doCreateBean
方法召嘶,聽說java中do
開都的方法都是真正做事的方法
doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//創(chuàng)建實例的BeanWrapper
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//從beanWrapper里面獲取包裝類對象
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//調用MergedBeanDefinitionPostProcessor
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//屬性注入
populateBean(beanName, mbd, instanceWrapper);
//進行 init-method初始化,主要是通知各個BeanPostProcessor
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
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);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName, "");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
doCreateBean
方法主要是做了以下事情:
- createBeanInstance 生成對象哮缺,并返回包裝類
- popoulateBean 進行屬性注入
- instantiateBean 進行init-method初始化和后置等處理弄跌,主要是通知各個BeanPostProcessor
總結
貼的代碼有點多,創(chuàng)建對象的一些邏輯還沒深究尝苇,繼續(xù)下去就怕很難閉合了碟绑。倒不如先來個總結。