我們知道,在調用getBean獲取bean實例的實例,首先會從緩存中獲取bean實例,如果沒有獲取到,就會去創建bean的時候。關於獲取bean實例,可以參考Spring源碼分析之getBean主流程分析,而本文將會對創建bean實例的主流程來做一個分析。而入口,當然是createBean(AbstractAutowireCapableBeanFactory)的方法。
下面來看源碼:
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//1:解析bean的類型
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
//2:處理 lookup-method 和 replace-method 配置,而Spring統稱爲override method
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
........
}
try {
//3:bean的後置處理器,如果有,這裏會返回代理的實例。AOP的實現基礎就是基於這裏來實現的
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
........
}
//來創建bean的實例
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
其主流程邏輯也是比較的簡單的:
- 對bean類型的解析
- 處理methodOverrides
- 處理bean實例的後置處理器。如果有,則返回一個代理的類。這裏實際上是判斷類有沒有實現InstantiationAwareBeanPostProcessor接口。
- 創建實例bean並返回。
下面我們來看看doCreateBean中的邏輯:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
//bean實例包裝類
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//從緩存中清理相關中的包裝類
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//創建bean的時候,這裏創建bean的實例有三種方法
//1:工廠方法創建
//2: 利用構造方法的方式注入
//3: 利用無參構造方法注入
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//這裏的bean應該是才被實例化的bean,還未被填充相關的屬性
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
.........
}
mbd.postProcessed = true;
}
}
//判斷是否是早期引用的bean,如果是,則允許其提前暴露引用
//這裏判斷的邏輯主要有三個:
//1:是否爲單例:isSingleton
//2:是否允許循環引用 :allowCircularReferences
//3:是否是在創建中的bean:isSingletonCurrentlyInCreation
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");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
Object exposedObject = bean;
try {
//填充bean的屬性
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
//初始化bean,過程如下:
//1:判斷是否實現了BeanNameAware,BeanClassLoaderAware以及
// BeanFactoryAware方法,如果有,則設置相關的屬性
//2: 調用bean初始化的前置操作
//3: 執行初始化的方法。
// 如果有initializingBean,則調用afterPropertiesSet
// 如果有InitMethod,則調用初始方法
//4: 調用bean初始化的後置操作
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<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
......
}
}
}
}
//註冊bean的銷燬邏輯
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
......
}
return exposedObject;
}
實際創建bean實例的邏輯如下:
1:創建bean的實例(工廠方法,構造器注入的方式,簡單初始化的方式)
2:是否允許其是否提前暴露引用,以便解決循環依賴的問題。
3:填充bean實例的屬性
4:初始化操作(初始方法前操作,調用初始化方法,執行初始化後的方法)
5:解決循環依賴相關的問題。
6:註冊bean的銷燬邏輯。
至此,整個創建bean實例的主流程就分析完成了,下面將以一個簡單的圖來更加形象的展示其主流程調用邏輯。