1. 程式人生 > 實用技巧 >Spring核心IOC原始碼解讀(四)getBean建立SpringBean物件

Spring核心IOC原始碼解讀(四)getBean建立SpringBean物件

  getBean方法會呼叫到AbstractBeanFactorydoGetBean()方法中去。下面看看AbstractBeanFactory 的類圖結構

 一、AbstractBeanFactory doGetBean()方法

  這個程式碼塊比較主要點在getSingleton()方法上

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
        @Nullable final Object[] args, boolean typeCheckOnly) throws
BeansException { ... // 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方法包含了,通過反射建立物件,填充物件成員變數等操作