Spring核心IOC原始碼解讀(四)getBean建立SpringBean物件
阿新 • • 發佈:2020-11-07
getBean方法會呼叫到AbstractBeanFactory的doGetBean()方法中去。下面看看AbstractBeanFactory 的類圖結構
一、AbstractBeanFactory doGetBean()方法
這個程式碼塊比較主要點在getSingleton()方法上
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throwsBeansException { ... // 1.嘗試獲取單例物件 Object sharedInstance = getSingleton(beanName); ... // 2.建立物件並獲取單例物件 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); } ... return (T) bean; }
下面是第1步中getSingleton()的具體程式碼
protected Object getSingleton(String beanName, boolean allowEarlyReference) { //嘗試從快取C中獲取單例物件 Object singletonObject = this.singletonObjects.get(beanName); //為獲取到並且物件在建立中 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { //從早期快取A中獲取物件 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { //獲取物件 singletonObject = singletonFactory.getObject(); //放入早期快取A this.earlySingletonObjects.put(beanName, singletonObject); //清除該物件的單例工廠快取B this.singletonFactories.remove(beanName); } } } } return singletonObject; }
下面是第2步中getSingleton()的具體程式碼
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { //從快取C中獲取 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) {
//標記當前物件正在建立
beforeSingletonCreation(beanName); ... //呼叫實現類的createBean方法 singletonObject = singletonFactory.getObject(); newSingleton = true; ... //如果是單例則做對應的快取操作 if (newSingleton) { addSingleton(beanName, singletonObject); }
//清除當前正在建立的快取
afterSingletonCreation(beanName); } return singletonObject; } } protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { //快取C this.singletonObjects.put(beanName, singletonObject); //清除快取B this.singletonFactories.remove(beanName); //清除快取A this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } }
二、AbstractBeanFactory createBean()方法,建立SpringBean物件的實現
createBean方法是一個抽象方法,由實現類實現,下面是實現類的結構
這個實現類createBean方法實現如下,首先獲取Class物件,再處理InstantiationAwareBeanPostProcessor介面的實現,然後建立Bean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { RootBeanDefinition mbdToUse = mbd; //獲得Bean的Class物件 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); //執行 InstantiationAwareBeanPostProcessor 介面的實現 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } //建立Bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
doCreateBean方法包含了,通過反射建立物件,填充物件成員變數等操作